This article is reproduced from: http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
RESTful is currently the most popular API design specification for the design of web data interfaces.
Its general principles are easy to grasp, but the details are not easy to get right. This article summarizes the design details of RESTful and introduces how to design an API that is easy to understand and use.
1. URL design
1.1 Verb + Object
The core idea of RESTful is that the data manipulation instructions issued by the client are all in the structure of "verb + object". For example, GET /articles
this command GET
is a verb and /articles
an object.
Verbs are usually five HTTP methods, corresponding to CRUD operations.
- GET: Read
- POST: Create
- PUT:更新(Update)
- PATCH: Update (Update), usually a partial update
- DELETE: Delete
According to the HTTP specification, all verbs are capitalized.
1.2 Verb coverage
Some clients use only GET
and POST
both methods. The server must accept the POST
analog three other methods PUT
( PATCH
, DELETE
, ).
At this time, the HTTP request sent by the client must add X-HTTP-Method-Override
attributes to tell the server which verb should be used to override the POST
method.
POST /api/Person/4 HTTP/1.1 X-HTTP-Method-Override: PUT
In the above code, X-HTTP-Method-Override
the method for specifying this request is PUT
, not POST
.
1.3 The object must be a noun
The object is the URL of the API and is the object of the HTTP verb. It should be a noun, not a verb. For example, /articles
this URL is correct, but the URL below is not a noun, so it is all wrong.
- / getAllCars
- /createNewCar
- /deleteAllRedCars
1.4 Plural URL
Since URL is a noun, should it be plural or singular?
There is no uniform rule, but a common operation is to read a collection, such as GET /articles
(read all articles), which obviously should be plural.
For the sake of consistency, it is recommended to use plural URLs, such as GET /articles/2
better than GET /article/2
.
1.5 Avoid multi-level URLs
A common situation is that resources require multi-level classification, so it is easy to write a multi-level URL, such as obtaining a certain type of article by a certain author.
GET /authors/12/categories/2
This kind of URL is not conducive to expansion, and the semantics are not clear. It often takes a while to understand the meaning.
It is better to use query strings for all levels except the first level.
GET /authors/12?categories=2
Here is another example to query published articles. You may design the following URL.
GET /articles/published
The query string is significantly better written.
GET /articles?published=true
Second, the status code
2.1 The status code must be accurate
For every request from the client, the server must respond. The response includes two parts: HTTP status code and data.
The HTTP status code is a three-digit number divided into five categories.
1xx
:Related Information2xx
:Successful operation3xx
: Redirect4xx
: Client error5xx
:Server Error
These five categories contain a total of more than 100 status codes, covering most of the possible situations. Each status code has a standard (or agreed) interpretation. The client can determine what happened only by looking at the status code, so the server should return the status code as accurate as possible.
API does not require 1xx
status codes. The precise meanings of the other four types of status codes are described below.
2.2 2xx status codes
200
The status code indicates that the operation was successful, but different methods can return a more accurate status code.
- GET: 200 OK
- POST: 201 Created
- PUT: 200 OK
- PATCH: 200 OK
- DELETE: 204 No Content
In the above code, the POST
return 201
status code indicates that a new resource is generated; the DELETE
return 204
status code indicates that the resource no longer exists.
In addition, the 202 Accepted
status code indicates that the server has received the request, but has not yet processed it, and will process it in the future, usually for asynchronous operations. Below is an example.
HTTP/1.1 202 Accepted { "task": { "href": "/api/company/job-management/jobs/2130040", "id": "2130040" } }
2.3 3xx status codes
API does not use 301
status code (permanent redirect) and 302
status code (temporary redirect, which 307
is also the meaning), because they can be returned by the application level, and the browser will jump directly. The API level does not need to consider these two cases.
The 3xx
status code used by the API , mainly 303 See Other
, refers to another URL. It 302
and 307
the meaning, just as "temporary redirect," The difference is that 302
, and 307
for the GET
request, and 303
for POST
, PUT
and DELETE
requests. After receiving 303
it, the browser will not automatically jump, but will let the user decide what to do next. Below is an example.
HTTP/1.1 303 See Other Location: /api/orders/12345
2.4 4xx status codes
4xx
The status code indicates a client error, mainly as follows.
400 Bad Request
: The server did not understand the client's request and did not do any processing.
401 Unauthorized
: The user did not provide authentication credentials or did not pass authentication.
403 Forbidden
: The user has passed the authentication, but does not have the necessary permissions to access the resource.
404 Not Found
: The requested resource does not exist or is unavailable.
405 Method Not Allowed
: The user has been authenticated, but the HTTP method used is not within his authority.
410 Gone
: The requested resource has been transferred from this address and is no longer available.
415 Unsupported Media Type
: The return format requested by the client is not supported. For example, the API can only return JSON format, but the client requires XML format.
422 Unprocessable Entity
: The attachment uploaded by the client cannot be processed, causing the request to fail.
429 Too Many Requests
: The number of client requests exceeds the limit.
2.5 5xx status codes
5xx
The status code indicates a server error. Generally speaking, the API does not disclose the detailed information of the server to the user, so only two status codes are enough.
500 Internal Server Error
: The client request is valid, and an accident occurred during the server processing.
503 Service Unavailable
: The server cannot process the request, it is generally used for website maintenance status.
Three, server response
3.1 Don't return to pure text
The data format returned by the API should not be a plain text, but a JSON object, because in this way can it return standard structured data. Therefore, the Content-Type
attributes of the HTTP header of the server response should be set application/json
.
When the client requests it, it must also clearly tell the server that it can accept JSON format, that is, the ACCEPT
attributes of the HTTP header of the request should also be set application/json
. Below is an example.
GET /orders/2 HTTP/1.1 Accept: application/json
3.2 When an error occurs, do not return a 200 status code
An inappropriate approach is to return the 200
status code even if an error occurs, and put the error message in the data body, as shown below.
HTTP/1.1 200 OK Content-Type: application/json { "status": "failure", "data": { "error": "Expected at least two items in list." } }
In the above code, after parsing the data body, the operation failed can be known.
This approach actually cancels the status code, which is completely undesirable. The correct approach is that the status code reflects the error that occurred, and the specific error information is returned in the data body. Below is an example.
HTTP/1.1 400 Bad Request Content-Type: application/json { "error": "Invalid payoad.", "detail": { "surname": "This field is required." } }
3.3 Provide links
The user of the API may not know how the URL is designed. One solution is to provide relevant links in the response to facilitate the next step. In this case, users only need to remember one URL, and they can discover other URLs. This method is called HATEOAS.
For example, all GitHub APIs are in the domain name api.github.com . By visiting it, you can get other URLs.
{ ... "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "gists_url": "https://api.github.com/gists{/gist_id}", "hub_url": "https://api.github.com/hub", ... }
In the above response, choose a URL to visit and you can get another URL. For users, there is no need to remember the URL design, just look it up step by step from api.github.com.
The format of HATEOAS is not uniformly regulated. In the above example, GitHub puts them together with other attributes. It would be better to separate related links from other attributes.
HTTP/1.1 200 OK Content-Type: application/json { "status": "In progress", "links": {[ { "rel":"cancel", "method": "delete", "href":"/api/status/12345" } , { "rel":"edit", "method": "put", "href":"/api/status/12345" } ]} }
Four, reference link
- RESTful API Design: 13 Best Practices to Make Your Users Happy, by Florimond Manca
- API design, by MicroSoft Azure
(Finish)