r3dlin3 / api-guidelines

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

REST API Guidelines

1. Introduction

This document is not a presentation of REST.

It presents guidelines for designing REST API. Guidelines shall provide consistency accross services.

The guidelines are based on various sources all listed below in the section References.

References

License

Creative Commons License

2. Consistency fundamentals

2.1. URL structure

Humans SHOULD be able to easily read and construct URLs.

2.1.1. Base URL

The API should be published under a base URL.

The base URL should distinguishely show its purpose by including either the term ``api"" in the FQDN or the path of the URL.

2.1.2. Versioning

Any API will have to evolve over time. There are several ways of versioning an API:

With a timestamp, a release number…
In the path, at the beginning or at the end of the URI
As a parameter of the request
In a HTTP Header
With an optional or mandatory versioning.

The API SHOULD include a version in the path.

The version can be on:

  • one digit (recommended)

  • 2 digits

  • a date

2.1.3. Plural names

For collection, the plural names is advised.

2.1.4. URI case

According to [rfc3986], URLs are "case sensitive" (except for the scheme and the host).

Regarding the URIs, spinal-case (which is highlighted by [rfc3986]) is recommended with lowercase letters.

Example:

POST /v1/specific-orders

2.1.5. Query case

The case of parameters SHOULD follow Body case convention

2.1.6. Last character

The last character of the URL SHOULD NOT be /.

2.1.7. URL length

The HTTP 1.1 message format, defined in RFC 7230, in section 3.1.1, defines no length limit on the Request Line, which includes the target URL. From the RFC:

HTTP does not place a predefined limit on the length of a request-line. […​] A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code.

Services that can generate URLs longer than 2,083 characters MUST make accommodations for the clients they wish to support. Here are some sources for determining what target clients support:

Also note that some technology stacks have hard and adjustable url limits, so keep this in mind as you design your services.

2.2. Authentication

Authentication should rely on OAuth2.0 and follow [rfc6750].

2.3. Supported methods

Operations MUST use the proper HTTP methods whenever possible, and operation idempotency MUST be respected. HTTP methods are frequently referred to as the HTTP verbs. The terms are synonymous in this context, however the HTTP specification uses the term method.

Below is a list of methods that Microsoft REST services SHOULD support. Not all resources will support all methods, but all resources using the methods below MUST conform to their usage.

Method Description Is Idempotent

GET

Return the current value of an object or a collection of object

True

PUT

Replace an object

True

DELETE

Delete an object

True

POST

Create a new object based on the data, or submit a command

False

HEAD

Return metadata of an object for a GET response. Resources that support the GET method MAY support the HEAD method as well

True

PATCH

Apply a partial update to an object

False

OPTIONS

Get information about a request; see below for details.

True

2.3.1. POST

POST operations SHOULD support the Location response header to specify the location of any created resource that was not explicitly named, via the Location header.

As an example, imagine a service that allows creation of hosted servers, which will be named by the service:

POST http://api.contoso.com/account1/servers

The response would be something like:

201 Created
Location: http://api.contoso.com/account1/servers/server321

Where "server321" is the service-allocated server name.

Services MAY also return the full metadata for the created item in the response.

2.3.2. PUT

Warning
What about the result of PUT? NoContent? Location?

2.4. Standard request headers

The table of request headers below SHOULD be used. Using these headers is not mandated, but if used they MUST be used consistently.

All header values MUST follow the syntax rules set forth in the specification where the header field is defined. Many HTTP headers are defined in [rfc7231] however a complete list of approved headers can be found in the IANA Header Registry.

Table 1. Request headers
Header Type Description

Authorization

String

Authorization header for the request

Accept

Content type

The requested content type for the response such as:

  • application/xml

  • text/xml

  • application/json

  • text/javascript (for JSONP)

Per the HTTP guidelines, this is just a hint and responses MAY have a different content type, such as a blob fetch where a successful response will just be the blob stream as the payload. For services following OData, the preference order specified in OData SHOULD be followed.

Accept-Encoding

Gzip, deflate

REST endpoints SHOULD support GZIP and DEFLATE encoding, when applicable. For very large resources, services MAY ignore and return uncompressed data.

Accept-Language

"en", "es", etc.

Specifies the preferred language for the response. Services are not required to support this, but if a service supports localization it MUST do so through the Accept-Language header.

Accept-Charset

Charset type like "UTF-8"

Default is UTF-8, but services SHOULD be able to handle ISO-8859-1.

Content-Type

Content type

Mime type of request body (PUT/POST/PATCH)

Prefer

return=minimal, return=representation

If the return=minimal preference is specified, services SHOULD return an empty body in response to a successful insert or update. If return=representation is specified, services SHOULD return the created or updated resource in the response. Services SHOULD support this header if they have scenarios where clients would sometimes benefit from responses, but sometimes the response would impose too much of a hit on bandwidth.

If-Match, If-None-Match, If-Range

String

Services that support updates to resources using optimistic concurrency control MUST support the If-Match header to do so. Services MAY also use other headers related to ETags as long as they follow the HTTP specification.

2.5. Standard response headers

Services SHOULD return the following response headers, except where noted in the "required" column.

Response Header Required Description

Content-Type

All responses

The content type

Content-Encoding

All responses

GZIP or DEFLATE, as appropriate

Preference-Applied

When specified in request

Whether a preference indicated in the Prefer request header was applied

ETag

When the requested resource has an entity tag

The ETag response-header field provides the current value of the entity tag for the requested variant. Used with If-Match, If-None-Match and If-Range to implement optimistic concurrency control.

2.6. Custom header

No need for now. To be specified if any.

2.7. PII parameters

Consistent with their organization’s privacy policy, clients SHOULD NOT transmit personally identifiable information (PII) parameters in the URL (as part of path or query string) because this information can be inadvertently exposed via client, network, and server logs and other mechanisms.

2.8. Response format

For organizations to have a successful platform, they must serve data in formats developers are accustomed to using, and in consistent ways that allow developers to handle responses with common code.

Web-based communication, especially when a mobile or other low-bandwidth client is involved, has moved quickly in the direction of JSON for a variety of reasons, including its tendency to be lighter weight and its ease of consumption with JavaScript-based clients.

2.8.1. Body case

snake_case seems adopted by most Web Giants, especially those relying on Ruby. However, the convention in JavaScript is the camelCased.

JSON property names SHOULD be camelCased, with first letter in lower case.

2.8.2. Clients-specified response format

In HTTP, response format SHOULD be requested by the client using the Accept header. This is a hint, and the server MAY ignore it if it chooses to, even if this isn’t typical of well-behaved servers. Clients MAY send multiple Accept headers and the service MAY choose one of them.

The default response format (no Accept header provided) SHOULD be application/json, and all services MUST support application/json.

2.8.3. Status code

HTTP Status Description

201 Created

Indicates that a resource has been created. Typical answer to PUT and POST requests, including a HTTP Header “Location” which points toward the new resource URL.

202 Accepted

The request has been accepted and will be processed later. It is a classic answer to asynchronous calls (for better UX or performances).

204 No Content

The request has been successfully processed, but there is nothing to return. It is often returned to a DELETE request.

206 Partial Content

Content returned is incomplete. Mostly returned by paginated answers.

400 Bad Request

Commonly used for calling errors if no other status matches.

401 Unauthorized

The request MUST be authenticated

403 Forbidden

Not enough rights

404 Not Found

The resource does not exist

405 Method not allowed

Either calling a method on this resource has no meaning, or the user is not authorized to make this call.

406 Not Acceptable

Nothing matches the Accept-* Header of the request. As an example, you ask for an XML formatted resource but it is only available as JSON

500 Server error

Execution problem has been encountered.

Warning
Should 206 implemented??

2.9. Errors

The RFC 7807 should be used as a standardized format for returning machine readable error responses from HTTP APIs.

RFC 7807 provides a standard format for returning problem details from HTTP APIs. In particular, it specifies the following:

  • Error responses MUST use standard HTTP status codes in the 400 or 500 range to detail the general category of error.

  • Error responses will be of the Content-Type application/problem, appending a serialization format of either json or xml: application/problem+json, application/problem+xml.

  • Error responses will have each of the following keys:

  • detail (string) - A human-readable description of the specific error.

  • type (string) - a URL to a document describing the error condition (optional, and "about:blank" is assumed if none is provided; should resolve to a human-readable document).

  • title (string) - A short, human-readable title for the general error type; the title should not change for given types.

  • status (number) - Conveying the HTTP status code; this is so that all information is in one place, but also to correct for changes in the status code due to the usage of proxy servers. The status member, if present, is only advisory as generators MUST use the same status code in the actual HTTP response to assure that generic HTTP software that does not understand this format still behaves correctly. ( instance (string) - This optional key may be present, with a unique URI for the specific error; this will often point to an error log for that specific response.

Example:

{
   "type": "https://example.net/validation-error",
   "title": "Your request parameters didn't validate.",
   "invalid-params": [ {
                         "name": "age",
                         "reason": "must be a positive integer"
                       },
                       {
                         "name": "color",
                         "reason": "must be 'green', 'red' or 'blue'"}
                     ]
}

3. Collections

3.1. Filter and paginate data

Filtering, paginating, sorting and searching will be done based on query parameters.

Parameters and results will follow OData specification

3.1.1. Paging

It is necessary to anticipate the paging of your resources in the early design phase of your API. It is indeed difficult to foresee precisely the progression of the amount of data that will be returned. Therefore, we recommend paginating your resources with default values when they are not provided by the calling client, for example with a range of values [0-25].

3.1.2. Filtering

Filtering consists in restricting the number of queried resources by specifying some attributes and their expected values. It is possible to filter a collection on several attributes at the same time and to allow several values for one filtered attribute.

3.1.3. Sorting

Sorting the result of a query on a collection of resources. A sort parameter should contain the names of the attributes on which the sorting is performed, separated by a comma.

3.1.4. Searching

A search is a sub-resource of a collection. As such, its results will have a different format than the resources and the collection itself. This allows us to add suggestions, corrections, and information related to the search. Parameters are provided the same way as for a filter, through the query-string, but they are not necessarily exact values, and their syntax permits approximate matching.

3.2. Item keys

Services MAY support durable identifiers for each item in the collection, and that identifier SHOULD be represented in JSON as "id". These durable identifiers are often used as item keys.

Collections that support durable identifiers MAY support delta queries.

3.3. Serialization

Collections are represented in JSON using standard array notation.

3.4. Caching

4. CORS

No need for now.

5. Best practices

5.1. HTTPS

HTTPS MUST be enforced.

5.2. Swagger/OpenAPI

The API should be documented following OpenAPI

About