This paper is a beta version of the API development specification of Dayu network, and it makes a lot of reference to the design of RESETful API which is common at present.
In order to better discuss the disputes and problems caused by the specification, this document has been sorted out and open source to Github, and you can add and mention the issue.
On the use of “willing verbs”
To avoid ambiguity, the document makes extensive use of “willing verbs”, which are explained as follows:
Have to (MUST)
Please do it unconditionally.MUST NOT
5. banOught to (SHOULD)
: Strongly recommended, but not required;Shouldn't (SHOULD NOT)
: Strongly not recommended, but not required;Can (MAY)
和OPTIONAL (OPTIONAL)
The word is used less frequently in this document.
See RFC 2119
agreement
The HTTPS protocol should be used when communicating with back-end services through apis.
API Root URL
The API root entry point should be kept as simple as possible. Here are two common EXAMPLES of URL roots:
- api.example.com/*
- example.com/api/*
If your application is big or you expect it to be big, put the API in a subdomain. This approach preserves some flexibility at scale.
Versioning
All apis must remain backward compatible, and you must introduce new versions of the API while ensuring that older versions are still available. Versioning support should be provided.
There are two common version numbers:
Embed version number in URL
api.example.com/v1/*
Copy the code
This approach is the version number intuitive, easy to debug; Alternatively, put the version number in the HTTP Header Header:
Version information is specified by media type
Accept: application/vnd.example.com.v1+json
Copy the code
VND indicates the standard Tree type, including x, PRS, and VND. The standard tree you use depends on the project you are developing
- Unregistered tree (
x
) mainly represents local and private environments - Private tree (
prs
) mainly refers to projects that have not been commercially released - Supplier tree (
vnd
) mainly refers to publicly published projects
The following parameters are the application name (usually the application domain name), version number, and expected return format.
There’s a lot of debate about where to put the version number, but since we spend most of our time developing with Laravel, we should use Dingo/API to build apps quickly, which takes a second approach to managing API versions, Standard HTTP Response has been integrated.
Endpoints
An endpoint is a URL that points to a particular resource or collection of resources. In the design of endpoints, you must follow the following conventions:
- The URL naming
Must be
All lowercase - Resources in URL (
resource
The naming of)Must be
Is a noun andMust be
It’s plural Must be
Preferred to useRestful
Type the URL of the- Cannot appear in URL
-
.Must be
With an underscore_
Instead of - URL
Must be
Is easy to read - URL
Must not
Exposing the server architecture
Let’s take a counter example
- https://api.example.com/getUserInfo?userid=1
- https://api.example.com/getusers
- https://api.example.com/sv/u
- https://api.example.com/cgi-bin/users/get_user.php?userid=1
Let’s do another column
- https://api.example.com/zoos
- https://api.example.com/animals
- https://api.example.com/zoos/{zoo}/animals
- https://api.example.com/animal_types
- https://api.example.com/employees
HTTP verbs
The specific types of operations on resources are represented by HTTP verbs. There are five common HTTP verbs (the corresponding SQL commands are in parentheses).
- GET (SELECT) : Retrieves one or more resources from the server.
- POST (CREATE) : Creates a resource on the server.
- PUT (UPDATE) : Updates the resource on the server (the client provides the full resource after the change).
- PATCH (UPDATE) : Updates resources on the server (the client provides the changed properties).
- DELETE (DELETE) : deletes resources from the server.
Among them
1 DELETE a resource. 2 Create a new resource. 3 Update a resource
For each endpoint, all possible COMBINATIONS of HTTP verbs and endpoints are listed below
Request method | URL | describe |
---|---|---|
GET | /zoos | List all zoos (ids and names, don’t be too specific) |
POST | /zoos | A new zoo has been added |
GET | /zoos/{zoo} | To obtain details of designated zoos |
PUT | /zoos/{zoo} | Update the specified zoo (entire object) |
PATCH | /zoos/{zoo} | Update the Zoo (some objects) |
DELETE | /zoos/{zoo} | Deleting a Specified Zoo |
GET | /zoos/{zoo}/animals | Retrieves a list of animals under the specified zoo (ID and name, not too detailed) |
GET | /animals | Lists all animals (ID and name). |
POST | /animals | Add new animals |
GET | /animals/{animal} | Get specific animal details |
PUT | /animals/{animal} | Update the specified animal (entire object) |
PATCH | /animals/{animal} | Update specified animals (partial objects) |
GET | /animal_types | Get all animal types (ID and name, not too detailed) |
GET | /animal_types/{type} | Gets details about the specified animal type |
GET | /employees | Retrieve the entire list of employees |
GET | /employees/{employee} | Retrieves a specified employee |
GET | /zoos/{zoo}/employees | Retrieve a list of employees (id and name) working at the zoo |
POST | /employees | Add designated new employees |
POST | /zoos/{zoo}/employees | Hire an employee at a specific zoo |
DELETE | /zoos/{zoo}/employees/{employee} | Fire an employee from a zoo |
Filtering
If there are many records, the server cannot return them all to the user. The API should provide parameters that filter the return results. Here are some common parameters.
- ? Limit =10: Specifies the number of records to return
- ? Offset =10: Specifies the start of the return record.
- ? Page =2&per_page=100: Specifies the number of pages and the number of records per page.
- ? Sortby = name&ORDER = ASC: Specifies by which attribute the return results are sorted, and in what order.
- ? Animal_type_id =1: Specifies a filter condition
All URL parameters must be all lowercase and must be in the form of an underscore.
Frequently used, complex queries should be tagged to reduce maintenance costs. Such as
GET /trades? status=closed&sort=sortby=name&order=asc# You can customize shortcuts for it
GET /trades/recently_closed
Copy the code
Authentication
Login authentication should be provided to API callers using OAuth2.0. You must obtain the Access Token through the login interface before invoking the API requiring identity authentication using the Token.
The endpoint design of Oauth is listed
- RFC 6749 /token
- Twitter /oauth2/token
- Fackbook /oauth/access_token
- Google /o/oauth2/token
- Github /login/oauth/access_token
- Instagram /oauth/authorize
The client that obtains the Access token must include in the response a data called expires_in, which indicates how many seconds the currently acquired token will expire.
{
"access_token": "token...."."token_type": "Bearer"."expires_in": 3600
}
Copy the code
When a client requests an API that requires authentication, it must include an access_token in the request header Authorization.
Authorization: Bearer token...
Copy the code
The server should return an invalid_token error or 401 error code when the access token expires after the specified number of seconds and is accessed again with an expired/invalid token.
HTTP / 1.1401 Unauthorized
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"error": "invalid_token"
}
Copy the code
In Laravel development, JWT should be used to manage your tokens and must not open request sessions in API middleware.
Response
All API responses must comply with the HTTP design specification, and the appropriate HTTP status code must be selected. All interfaces must not return an HTTP response with status code 200, for example:
HTTP / 1.1200 ok
Content-Type: application/json
Server: example.com
{
"code": 0."msg": "success"."data": {
"username": "username"}}Copy the code
or
HTTP / 1.1200 ok
Content-Type: application/json
Server: example.com
{
"code": - 1."msg": "This activity does not exist.",}Copy the code
The following table lists the common HTTP status codes
Status code | describe |
---|---|
1xx | The delegate request has been accepted and needs to continue processing |
2xx | The request was successful, and the desired response header or data body is returned with this response |
3xx | redirect |
4xx | Error caused by client |
5xx | Error caused by server |
A 2XX response is returned only if the request from the client is properly processed, so when the API returns a status code of type 2XX, the front end must assume that the request was successfully processed.
It must be emphasized that all apis must not return status codes of type 1XX. When an API error occurs, the details at the time of the error must be returned. Currently, there are two common methods for returning error messages:
1. Put the error details in the HTTP response header;
X-MYNAME-ERROR-CODE: 4001
X-MYNAME-ERROR-MESSAGE: Bad authentication token
X-MYNAME-ERROR-INFO: http://docs.example.com/api/v1/authentication
Copy the code
2, directly into the response entity;
HTTP / 1.1401 Unauthorized
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 10:02:59 GMT
Connection: keep-alive
{"error_code":40100."message":"Unauthorized"}
Copy the code
For legibility and client-side ease of handling, we must place the error message directly in the response entity, and the error format should meet the following format:
{
"message": "The resource you are looking for does not exist"."error_code": 404001
}
Copy the code
The error_code must correspond to the HTTP status code to facilitate error code classification, for example:
HTTP / 1.1429 Too Many Requests
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 10:15:52 GMT
Connection: keep-alive
{"error_code":429001."message":"You're doing it too often."}
Copy the code
HTTP / 1.1403 Forbidden
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 10:19:27 GMT
Connection: keep-alive
{"error_code":403002."message":"User disabled"}
Copy the code
Error messages returned should include both developer and user prompts. The former can be easily debugged by developers, and the latter can be directly displayed to end users. For example:
{
"message": "Error messages displayed directly to end users"."error_code": "Service error code"."error": "Error message for developers to view"."debug": [
"Error stack. Debug must be enabled to exist."]}Copy the code
The API returns are detailed below.
200 ok
The 200 status code is the most common HTTP status code and must be returned in all successful GET requests. The HTTP response entity part must be data directly, without extra wrapping.
Examples of errors:
HTTP / 1.1200 ok
Content-Type: application/json
Server: example.com
{
"user": {
"id":1."nickname":"fwest"."username": "example"}}Copy the code
Correct examples:
1. Obtain details about a single resource
{
"id": 1."username": "godruoyi"."age": 88,}Copy the code
2. Get the resource set
[{"id": 1."username": "godruoyi"."age": 88}, {"id": 2."username": "foo"."age": 88,}]Copy the code
3. Additional media information
{
"data": [{"id": 1."avatar": "https://lorempixel.com/640/480/?32556"."nickname": "fwest"."last_logined_time": "The 2018-05-29 04:56:43"."has_registed": true
},
{
"id": 2."avatar": "https://lorempixel.com/640/480/?86144"."nickname": "zschowalter"."last_logined_time": "The 2018-06-16 15:18:34"."has_registed": true}]."meta": {
"pagination": {
"total": 101."count": 2."per_page": 2."current_page": 1."total_pages": 51."links": {
"next": "http://api.example.com?page=2"}}}}Copy the code
Where pages and other additional media information must be placed in the META field.
201 Created
This status code should be returned when the server successfully creates data. The common application scenario is to submit user information through POST, for example:
- A new user is added
- Upload a picture
- A new activity is created
Etc., can return 201 status code. Note that you can choose to return the data for the new user after the user is created successfully
HTTP / 1.1201 Created
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 24 Jun 2018 09:13:40 GMT
Connection: keep-alive
{
"id": 1."avatar": "https:\/\/lorempixel.com\/640\/480\/?32556"."nickname": "fwest"."last_logined_time": "The 2018-05-29 04:56:43"."created_at": "The 2018-06-16 17:55:55"."updated_at": "The 2018-06-16 17:55:55"
}
Copy the code
You can also return an empty HTTP Response such as:
HTTP / 1.1201 Created
Server: nginx / 1.11.9Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 24 Jun 2018 09:12:20 GMT
Connection: keep-alive
Copy the code
We should use the second approach here, because in most cases, the client only needs to know whether the request operation was successful or not, and does not need to return information about the new resource.
202 Accepted
This status code indicates that the server has received the request from the client, but has not yet started processing it. Common SMS sending, email notification, template message push, and other time-consuming scenarios requiring queue support;
When this status code is returned, the response entity must be null.
HTTP/1.1 202 Accepted Server: nginx/1.11.9 Content-type: text/ HTML; HTTP/1.1 202 Accepted Server: nginx/1.11.9 Content-type: text/ HTML; charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 24 Jun 2018 09:25:15 GMT Connection: keep-aliveCopy the code
204 No Content
The status code indicates that the response entity does not contain any data, where:
- In the use of
DELETE
Method to delete a resourcesuccessfulWhen,Must be
Returns the status code - use
PUT
,PATCH
Method update datasuccessful,Should be
Returns this status code
HTTP / 1.1204 No Content
Server: nginx / 1.11.9Date: Sun, 24 Jun 2018 09:29:12 GMT
Connection: keep-alive
Copy the code
3 xx redirection
All apis must not return status codes of type 3XX. Because 3XX type response format is generally in the following format:
HTTP/1.1 302 Found Server: nginx/1.11.9 Content-Type: text/ HTML; charset=UTF-8 Transfer-Encoding: chunked Cache-Control: no-cache, private Date: Sun, 24 Jun 2018 09:41:50 GMT Location: https://example.com Connection: keep-alive
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0; url=https://example.com" />
<title>Redirecting to https://example.com</title>
</head>
<body>
Redirecting to <a href="https://example.com">https://example.com</a>.
</body>
</html>
Copy the code
The API must not return a response with a pure HTML structure; If you must use the redirection function, you should return a 3XX response with an empty response entity and place the Location field in the response header:
HTTP / 1.1302 Found
Server: nginx / 1.11.9Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 24 Jun 2018 09:52:50 GMT
Location: https://godruoyi.com
Connection: keep-alive
Copy the code
400 Bad Request
The server should abandon the request due to obvious client errors (for example, incorrect request syntax, invalid request, invalid signature, etc.).
The server must return the status code if it cannot find one of the other 4XX types to indicate an error type.
HTTP / 1.1400 Bad Request
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 13:22:36 GMT
Connection: keep-alive
{"error_code":40000."message":"Invalid signature"}
Copy the code
401 Unauthorized
This status code indicates that the current request requires authentication. This status code must be returned in the following cases.
- An unauthenticated user accesses an API that requires authentication
- Access_token is invalid or expired
After receiving the 401 response, the client should prompt the user for the next login operation.
HTTP / 1.1401 Unauthorized
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
WWW-Authenticate: JWTAuth
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 13:17:02 GMT
Connection: keep-alive
"message":"Token Signature could not be verified."."error_code": "40100"}
Copy the code
403 Forbidden
The status code simply means that the server does not have access to the request, and the server receives the request but refuses to provide services.
For example, when a common user requests an operation administrator, the status code must be returned.
HTTP / 1.1403 Forbidden
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 13:05:34 GMT
Connection: keep-alive
{"error_code":40301."message":"Insufficient authority"}
Copy the code
404 Not Found
The status code indicates that the requested resource does not exist
- Get user information that does not exist (get /users/9999999)
- Access a nonexistent endpoint
The status code must be returned. If the resource is permanently gone, a 410 response should be returned.
405 Method Not Allowd
This status code must be returned when the HTTP request method used by the client is not allowed by the server.
For example, a client calls the POST method to access an API that only supports the GET method
The response must return an Allow header representing a list of request methods that the current resource can accept.
HTTP / 1.1405 Method Not Allowed
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Allow: GET, HEAD
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 12:30:57 GMT
Connection: keep-alive
{"message":"405 Method Not Allowed"."error_code": 40500}
Copy the code
406 Not Acceptable
The API should return this status code when the data format specified by the client is not supported. Such as when apis that support JSON and XML output are specified to return data in YAML format.
The Http protocol usually specifies the data format by accepting the request header
408 Request Timeout
This status code must be returned when a client request times out. This status code indicates that the client request times out. Do not return this status code when a third-party API call times out.
409 Gonfilct
This status code indicates that the request cannot be processed because of a conflict. If the API provides the registration function by mobile phone number, this status code must be returned when the mobile phone number submitted by the user already exists.
HTTP / 1.1409 Conflict
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 12:19:04 GMT
Connection: keep-alive
{"error_code":40900."message":"Mobile number already exists"}
Copy the code
410 Gone
Similar to 404, this status code also indicates that the requested resource does not exist, except that 410 further indicates that the requested resource does not exist and will not exist in the future. After receiving the 410 status code, the client should stop requesting the resource again.
413 Request Entity Too Large
This status code indicates that the server refuses to process the current request because the size of entity data submitted by the request is larger than the server is willing or able to process.
In this case, the server can close the connection to prevent the client from continuing to send the request.
If the condition is temporary, the server should return a retry-after response header telling the client how long it can Retry.
414 Request-URI Too Long
This status code indicates that the request URI is longer than the server can interpret, so the server refuses to service the request.
415 Unsupported Media Type
It usually indicates that the server does not support the data format specified in the content-type header of the client request. This status code should be returned if you put XML data into an API that only accepts JSON format and send it to the server.
This status code can also be used when only image files are allowed to be uploaded, but the media file submitted by the client is illegal or not of the image type. The status code should be returned:
HTTP / 1.1415 Unsupported Media Type
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 12:09:40 GMT
Connection: keep-alive
{"error_code":41500."message":"Image formats not allowed to upload"}
Copy the code
429 Too Many Request
The status code indicates that the number of user requests exceeds the upper limit. If the API is set to 60 requests per minute, the status code is returned when the number of requests exceeds 60 within a minute. The following headers should also be added to the response header:
X-ratelimit-limit: 10 Request rate (the unit is hour/minute. The unit is 10 times /5 minutes.) X-ratelimit-Remaining: 0 Number of Remaining requests x-ratelimit-reset: 1529839462 Reset time retry-after: 120 Time to wait for the next access (seconds)Copy the code
example
HTTP / 1.1429 Too Many Requests
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1529839462
Retry-After: 290
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 11:19:32 GMT
Connection: keep-alive
{"message":"You have exceeded your rate limit."."error_code":42900}
Copy the code
Rate Limit support must be set for all apis.
500 Internal Server Error
This status code must be thrown when the server fails, and for all 500 errors, complete error information support should be provided to facilitate debugging.
503 Service Unavailable
This status code indicates that the server is temporarily unavailable. It is returned when the server needs maintenance or when a third-party API request times out or is unreachable. If the API service is stopped, a retry-after header should be added to the response indicating the number of seconds before the server can be accessed again.
HTTP / 1.1503 Service Unavailable
Server: nginx / 1.11.9Content-Type: application/json
Transfer-Encoding: chunked
Cache-Control: no-cache, private
Date: Sun, 24 Jun 2018 10:56:20 GMT
Retry-After: 60
Connection: keep-alive
{"error_code":50300."message":"Service under maintenance"}
Copy the code
For other HTTP status codes, see HTTP Status Code – Wikipedia.
Copyright statement
Article published by Erlin Xu’s Chatty Miscellaneous Fish, freely reproduced – non-commercial – non-derivative – Remain signed (Creative Commons 3.0 license)
Recommended reference
restful-api-design-references
Principles of Good RESTful API Design
Understanding RESTful Architecture
RESTful API design Guide
HTTP status code – Wikipedia