A RESTful API or service is based on the representational state transfer architectural style and uses HTTP requests to GET, PUT, POST, and DELETE data.
The purpose of this article is to provide design and implementation guidelines for RESTful APIs.
Since REST is generally tightly tied to HTTP the document also includes the key applicable HTTP concepts that are important.
The OpenAPI Specification (OAS) will be used to document the REST contracts. The specification and tools can be found at http://swagger.io/.
The URI should:
- Be concise and easy to remember
- Identify the target resource
- Have only nouns and no verbs. It identifies a resource in hierarchy of the data domain and not what action to do. The HTTP verbs (GET, PUT, DELETE, POST) provide action. GET = Search/SELECT, PUT = UPDATE, POST = CREATE, and DELETE = DELETE. (POST with an ID is also a update)
- Be hierarchical or modular. Think of it as directory structure. The root part should identify data domain.
The following URI standards also apply to the URI:
- Resource names should be plural
- Locators go in URI resource path (IDs)
- Use query string filters to select which subset of data will be returned
- Content is transmitted in the request body (query strings, http multipart, JSON, XML)
- All REST interfaces must be versioned.
- HTTP protocol support for versioning should be used.
- Use accept header – also referred to as content negotiation. Client should pass version information in ‘Accept’ request header. E.g. Accept: application/xml;version=1.3.
- If no version in accept header then assume latest version – this allows browsing of the latest version
- Use HTTP specified return code if requested version is not supported.
- Using a version in the URI (resource) effectively creates a different resource – there may be situations where this is intention. For example, APIs for specific versions of standards are probably different resources and therefore putting the version of the standard in the URI makes sense.
These versioning recommendations were developed based on experience and research. The results of web-based research are described in the Microsoft Word listed below.
Services should use standard HTTP header mime types for request and response. E.g. Client should specify Accept header to specify type of the response. The service should include appropriate content-type to specify type of the response. Examples of accept header and content-type header values are application/xml and application/json. (Also see “HTTP Header Fields” section below.)
Mime media types are listed at https://www.iana.org/assignments/media-types/media-types.xhtml.
The set of common methods for HTTP/1.1 is:
HTTP Header Fields
|Accept||The Accept request-header field can be used to specify certain media types which are acceptable for the response.|
|Authorization||The Authorization field value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested.|
|Content-Type||The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.|
|Host||The Host request-header field specifies the Internet host and port number of the resource being requested, as obtained from the original URI given by the user or referring resource (generally an HTTP URL). The Host field value MUST represent the naming authority of the origin server or gateway given by the original URL. This allows the origin server or gateway to differentiate between internally-ambiguous URLs, such as the root “/” URL of a server for multiple host names on a single IP address.|
|Location||The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource. For 201 (Created) responses, the Location is that of the new resource which was created by the request.|
|Referer||The Referer[sic] request-header field allows the client to specify, for the server’s benefit, the address (URI) of the resource from which the Request-URI was obtained (the “referrer”, although the header field is misspelled.) The Referer request-header allows a server to generate lists of back-links to resources for interest, logging, optimized caching, etc. It also allows obsolete or mistyped links to be traced for maintenance. The Referer field MUST NOT be sent if the Request-URI was obtained from a source that does not have its own URI, such as input from the user keyboard.|
Accept and Content media types are listed at https://www.iana.org/assignments/media-types/media-types.xhtml.
HTTP Status Codes
Service should use HTTP status codes to communicate success and errors to client. Minimize use of custom HTTP status codes as it adds to additional contract and requires clients to handle them differently. Reason phrase of HTTP and response headers should be used to provide additional contextual information about error.
HTTP Status Codes fall into five (5) categories:
- Client Error
- Server Error
|200 OK||equest was fulfilled successfully and the response is sent to the client||Success||Success|
|201 Created||Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource|
|202 Accepted||The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.|
|204 No Content||Response to a successful request that won’t be returning a body (like a DELETE request)|
|400 Bad Request||Request could not be understood by the server due to malformed syntax|
|400 Bad Request||Request could not be understood by the server due to malformed syntax||InvalidContent||Content validation errors|
|400 Bad Request||Request could not be understood by the server due to malformed syntax||InvalidKey||API Key is invalid|
|401 Unauthorized||When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser|
|403 Forbidden||Server understood the request, but refusing to fulfill it (When authentication succeeded but authenticated user doesn’t have access to the resource)||Access Denied||Not permitted to access the URI.|
|404 Not Found||Server has not found anything matching the request URI|
|404 Not Found||Server has not found anything matching the request URI||NoSuchVersion||Indicates that the version ID specified in the request does not match an existing version.|
|405 Method Not Allowed||When an HTTP method is being requested that isn’t allowed for the authenticated user. The response MUST include an Allow header containing a list of valid methods for the requested resource.|
|406 Not Acceptable||The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.|
|408 Request Timeout||The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time.|
|410 Gone||Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions|
|413 Request Entity Too Large||The server is refusing to process a request because the request entity is larger than the server is willing or able to process. The server MAY close the connection to prevent the client from continuing the request.|
|414 Request URI Too Long||The server is refusing to service the request because the Request-URI is longer than the server is willing to interpret.|
|415 Unsupported Media Type||If incorrect content type was provided as part of the request|
|429 Too Many Requests||To prevent abuse, it is standard practice to add some sort of rate limiting to an API. RFC 6585 introduced a HTTP status code 429 Too Many Requests to accommodate this.||TooManyRequests||Request rejected due to rate limiting.|
|500 Internal Server Error||Server encountered an unexpected condition which prevented it from fulfilling the request||InternalError||We encountered an internal error. Please try again.|
|501 Not Implemented||The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.|
|502 Bad Gateway||The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.|
|503 Service Unavailable||Server is currently unable to handle the request due to maintenance of server or overloading of server. Use retry_after header.||ServiceUnavailable||Service is not available due to either maintenance or load. Please try again later.|
|504 Gateway Timeout||The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed to access in attempting to complete the request.|