RESTful design Method 1. Domain name
The API should be deployed under a dedicated domain name whenever possible.
https://api.example.com
If you determine that the API is simple, there is no further extension, consider placing it under the primary domain name.
https://example.org/api/
2. Version (Versioning)
The version number of the API should be placed in the URL.
http://www.example.com/app/1.0/foohttp://www.example.com/app/1.1/foohttp://www.example.com/app/2.0/foo
Another option is to place the version number in the HTTP header information, but not as convenient and intuitive as placing the URL. GitHub uses this approach.
Because different versions can be understood as different representations of the same resource, the same URL should be used. The version number can be distinguished in the Accept field of the HTTP request header information (see Versioning REST Services):
Accept:vnd.example-com.foo+json; version=1.0Accept:vnd.example-com.foo+json; version=1.1Accept:vnd.example-com.foo+json; version=2.0
3. Path (Endpoint)
The path is also called the "End point" (endpoint), which represents the specific URL of the API, each of which represents a resource (resource)
(1) Resources as URLs, only nouns, cannot have verbs, and the use of nouns often correspond with the table name of the database.
For example, the following are bad examples:
/getproducts/listorders/retreiveclientbyorder?orderid=1
For a concise structure, you should always use nouns. In addition, the HTTP method can be used to detach the name of the resource in the URL operation.
Get///PRODUCTS/4: Will get product 4/PRODUCTS/4: will be more new products 4
(2) Nouns in the API should use complex numbers. Regardless of child resources or all resources.
For example, the API to get a product can be defined like this
Get a single product: HTTP://127.0.0.1:8080/APPNAME/REST/PRODUCTS/1 get All Products: http://127.0.0.1:8080/appname/rest/ Products
3. HTTP verbs
For the specific operation type of the resource, it is represented by an HTTP verb.
The usual HTTP verbs have the following four (the corresponding SQL command in parentheses).
- GET (SELECT): Remove resources from the server (one or more items).
- POST (Create): Creates a new resource on the server.
- PUT (UPDATE): Updates the resource on the server (the client provides a full resource after the change).
- Delete: Deletes a resource from the server.
There are also three infrequently used HTTP verbs.
- PATCH Update: The server updates (updates) the resource (the client provides the changed properties).
- HEAD: Gets the metadata for the resource.
- OPTIONS: Gets information about which properties of a resource are available to the client to change.
Here are some examples.
GET///zoos//zoos//zoos//zoos//zoos/id//zoos/id/ ANIMALS/ID: Delete a designated animal from a designated zoo
4. Filtering information (Filtering)
If the number of records is large, the server will not be able to return them to the user. The API should provide parameters to filter the returned results.
The following are some common parameters.
limit=10: Specify the number of records to return? Offset=10: Specifies the start position of the returned record.page =2&per_page=100: Specifies the number of pages, and how many records per page. SortBy=name&order=ASC: Specifies which attribute the returned result is sorted by, and the sort order.? animal_type_id= 1: Specify filter criteria
The design of the parameter allows redundancy, which allows the API path and URL parameters to be duplicated occasionally. For example, the meaning of Get/zoos/id/animals and Get/animals?zoo_id=id is the same.
6. Status code (state Codes)
The status code and prompt information returned by the server to the user is usually the following (the HTTP verb corresponding to the status code in square brackets).
- $ OK-[GET]: The server successfully returned the data requested by the user
- 201 CREATED-[Post/put/patch]: User new or modified data succeeded.
- 202 Accepted-[*]: Indicates that a request has entered the background queue (asynchronous task)
- 204 NO CONTENT-[delete]: User deleted data successfully.
- INVALID request-[Post/put/patch]: The user has made an error and the server has not done new or modified data
- 401 Unauthorized-[*]: Indicates that the user does not have permissions (token, user name, password error).
- 403 Forbidden-[*] indicates that the user is authorized (as opposed to a 401 error), but access is forbidden.
- 404 Not FOUND-[*]: The user makes a request against a nonexistent record, the server does not operate, the operation is idempotent.
- 406 Not acceptable-[GET]: User requested format is not available (such as user request JSON format, but only XML format).
- 410 Gone-[get]: The resource requested by the user is permanently deleted and will no longer be available.
- 422 unprocesable Entity-[Post/put/patch] A validation error occurs when an object is created.
- $ INTERNAL Server Error-[*]: The server is having errors and the user will not be able to determine if the request was successful.
Full list of status codes see
Https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
7. Fault handling (Error handling)
If the status code is 4xx, the server should return an error message to the user. In general, error is used as the key name in the returned information, and error information is used as the key value.
{ "Invalid API key"}
8. Return results
For different operations, the results returned by the server to the user should conform to the following specifications.
- Get/collection: Returns a list of resource objects (arrays)
- Get/collection/resource: Returns a single Resource object
- Post/collection: Returns the newly generated resource object
- Put/collection/resource: Returns the full resource object
- Patch/collection/resource: Returns the full resource object
- Delete/collection/resource: Returns an empty document
9. Hypermedia (hypermedia API)
RESTful APIs are best done hypermedia (that is, providing links to the returned results, and connecting to other API methods), so that users do not look up documents and know what to do next.
For example, the GitHub API is the design that accesses api.github.com to get a list of URLs for all available APIs.
{"current_user_url""https://api.github.com/user" ,"authorizations_url""https://api.github.com/ Authorizations",// ...}
As you can see from the above, if you want to get information about the current user, you should go to the api.github.com/user and get the results below.
{ "message""Requires authentication", " Documentation_url " " Https://developer.github.com/v3 " }
The above code indicates that the server gives the prompt information and the URL of the document.
10. Other
The data format returned by the server should use JSON as much as possible and avoid using XML.
Urlpatterns ={URL (r'^index/$', views.index), url (r'^books/$', views. Booksapiview.as_view ()), URL (r'^books/(? p<pk>\d+)/$', views. Bookapiview.as_view ()), URL (r'^heros/$', views. Herosapiview.as_view ()), URL (r'^heros/(? p<pk>\d+)/$', views. Heroapiview.as_view ()),}
Simple implementation of the Restframework-style API interface in Demo:django;
ImportJSON fromDjango.formsImportmodel_to_dict fromDjango.httpImportJsonresponse fromDjango.shortcutsImportHttpResponse fromDjango.viewsImportView fromApp001.modelsImportBookInfo fromApp001.modelsImportHeroinfodefIndex (Request):returnHttpResponse ("OK")classBooksapiview (View):defget (self, request):"""Check all Books:p Aram Request:: Return:"""Queryset=BookInfo.objects.all (). VALUES () Book_list=[] book_list=list (Queryset)returnJsonresponse (Book_list, safe=False)defpost (self, request):"""new book:p Aram Request:: Return:"""json_bytes=request.body json_str=Json_bytes.decode () book_dict=json.loads (JSON_STR)#Book = BookInfo.objects.create ( #btitle = Book_dict.get ("Btitle"), #bpub_date = Datetime.strptime (Book_dict.get ("Bpub_date"), '%y-%m-%d '). Date (), # )Book =BookInfo.objects.create (**book_dict)returnJsonresponse ({"ID": Book.id,"Btitle": Book.btitle,'bpub_date': Book.bpub_date,'Bread': Book.bread,'bcomment': Book.bcomment,#' image ': Book.image.url if book.image Else '}, status=201)classBookapiview (View):"""get information on a single book""" defget (self, request, PK):Try: Book= BookInfo.objects.get (id=PK)exceptException as E:Print(e)returnHttpResponse (status=404) Book_dict=model_to_dict (book)returnjsonresponse (book_dict)defput (self, request, PK):"""Modify book information:p Aram Request::p Aram PK:: return:""" Try: Book= BookInfo.objects.get (id=PK)exceptException as E:Print(e)returnHttpResponse (status=404) #Calibration Parametersjson_bytes=request.body json_str=Json_bytes.decode () book_dict=json.loads (JSON_STR) BookInfo.objects.filter (ID=PK). Update (* *book_dict)#From django.forms.models import model_to_dictBook_dict = Model_to_dict (BookInfo.objects.get (id=PK)) returnjsonresponse (book_dict)defDelete (self, request, PK):"""Delete:p Aram request::p Aram PK:: return:""" Try: Book= BookInfo.objects.get (id=PK)exceptException as E:Print(e)returnHttpResponse (status=404) Book.delete ()returnHttpResponse (status=204)classHerosapiview (View):defget (self, request): Hero=HeroInfo.objects.all (). VALUES () Hero=list (Hero)returnJsonresponse (Hero, safe=False)defpost (self, request): Json_bytes=request.body json_str=Json_bytes.decode () hero_dict=json.loads (json_str) Hero="" Try: Hero= HeroInfo.objects.create (* *hero_dict)exceptException as E:Print(e)returnHttpResponse (status=404) returnJsonresponse (Model_to_dict (Hero), status=201)classHeroapiview (View):defget (self, request, PK): Hero= HeroInfo.objects.get (id=PK)returnJsonresponse (Model_to_dict (Hero))defput (self, request, PK):"""Modify book:p Aram request::p Aram PK:: return:""" Try: Hero= HeroInfo.objects.get (id=PK)exceptException as E:Print(e)returnHttpResponse (status=404) Json_bytes=request.body json_str=Json_bytes.decode () json_dict=json.loads (json_str) Hero= HeroInfo.objects.filter (ID=PK). Update (* *json_dict) hero_dict= Model_to_dict (HeroInfo.objects.get (id=PK)) returnjsonresponse (hero_dict)defDelete (self, request, PK):Try: Hero= HeroInfo.objects.get (id=PK)exceptException as E:Print(e)returnHttpResponse (status=404) Hero.delete ()returnHttpResponse (status=204)
Views function
Django REST Framework API Development