Created
November 13, 2015 18:56
-
-
Save markglenfletcher/d35ea94ff48be37146ea to your computer and use it in GitHub Desktop.
API Design Guidelines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Separate Concerns | |
Path indicates the identity of the resources | |
E.g. /stories/1 | |
The body transfers the contents | |
E.g. { 'story': { 'name':'My Story' } } | |
Headers to communicate metadata | |
Always SSL | |
respond to non-secure connections with 403 Forbidden | |
Do not redirect! | |
Always scope to API version | |
Require version information in the Accepts header | |
This should be a requirement for the client to ship | |
Avoid default versions | |
E.g. Accept: application/vnd.heroku+json; version=3 | |
Support etags for caching | |
Identify the specific version of the resource | |
This allows users to cache resources | |
If-None-Match header | |
Provide a request-id header in each response | |
Use a UUID value | |
Very useful for logging and debugging purposes | |
Divide large responses across multiple requests using Range headers | |
Range headers specify when more data is available | |
Requests | |
Accept Serialized JSON in request bodies | |
Use plurialised resource names for resources with collections | |
Unless the resource is a singleton | |
Maintains consistency across the API | |
Use an actions prefix for actions on a Resource outside of normal REST | |
Use consistent path formats across the entire API | |
Use downcased and dash-separated path names | |
Downcase attribute names but underscore separated for ease of use in JS | |
Try to accept other attributes as identifiers, where possible | |
Examples: | |
ID and Name | |
UUID and ID and Name | |
Ensure uniquness of the identifier | |
Minimise path nesting | |
Resources nested under another can also be found using their own identifier | |
For example | |
/apps/:app_id instead of /users/:user_id/apps/:app_id | |
Rate limit requests | |
Protect the health of the service | |
Maintain high service quality | |
Responses | |
Use appropriate status codes, always | |
2xx SUCCESS | |
200 - OK | |
Request succeeded for a GET call | |
Request succeeded for a PATCH or DELETE call that completed synchronously | |
Request succeeded for a PUT call that synchronously updated an existing resource | |
201 - CREATED | |
Request succeeded for a POST call that completed synchronously | |
Request succeeded for a PUT call that synchronously created an instance | |
202 - ACCEPTED | |
Request accepted for a POST, PUT, PATCH or DELETE that will be processed asynchronously | |
206 - PARTIAL CONTENT | |
Request succeeded on GET, but a response that contains only part of the requested data set was returned | |
4xx CLIENT ERROR | |
401 - UNAUTHORIZED | |
Request failed because the user is not authenticated | |
403 - FORBIDDEN | |
Request failed because the user is not authorized access to the requested resource | |
404 - NOT FOUND | |
422 - UNPROCESSABLE ENTITY | |
Request was understood but contained invalid parameters | |
429 - TOO MANY REQUESTS | |
Consumer has been rate-limited, try later | |
5xx SERVER ERROR | |
500 - INTERNAL SERVER ERROR | |
An unexpected error occurred at the server's side | |
Provide the full representation of the resource in the response | |
Full responses must use the 200 or 201 response codes | |
202 responses won't be expected to provide the full representation | |
Provide Resource UUIDs | |
and enable the consumer to request resources using this UUID | |
Provider created_at and updated_at timestamps for all resources | |
Accept and return timestamps only in UTC and ISO8601 Format | |
E.g. "finished_at": "2012-01-01T12:00:00Z" | |
Foreign key references should be nested with the response body | |
This allows the associated resource to alter without affecting the top-level of the response body | |
E.g. { | |
'story': { | |
name: 'My Story', | |
'author': { | |
'id': 1 | |
}, | |
date_of_birth: '' | |
} | |
} | |
Generate consistently structured error messages | |
Machine readable by including an error ID | |
Human readable by including an error message | |
Optional URL pointing to further information about the error | |
Provide information regarding rate limits in each response | |
Return the number of request tokens in the RateLimit-Remaining response header | |
Minify JSON in all responses | |
Remove whitespace to reduce the size of responses | |
Perhaps provide a means for a client to receive verbose/pretty responses, but only if specified | |
Could be supplied via a query parameter or request header | |
Provide machine readable JSON schema for whole API | |
https://github.com/interagent/prmd | |
Provide human-readable documentation | |
For client developers to understand the API | |
Provide documentation for each endpoint | |
API overview | |
Authentication | |
Acquiring and using authentication tokens | |
API versioning | |
How to select desired API version | |
Common request and response headers | |
Error serialisation format | |
Examples of API usage | |
Provide executable examples | |
Describe the stability of the API | |
Don't make backwards incompatible changes | |
If necessary create a new API with a new version number |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment