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 NOT5. ban
  • Ought 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 namingMust beAll lowercase
  • Resources in URL (resourceThe naming of)Must beIs a noun andMust beIt’s plural
  • Must bePreferred to useRestfulType the URL of the
  • Cannot appear in URL-.Must beWith an underscore_Instead of
  • URL Must beIs easy to read
  • URL Must notExposing 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 ofDELETEMethod to delete a resourcesuccessfulWhen,Must beReturns the status code
  • usePUT,PATCHMethod update datasuccessful,Should beReturns 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