This is a specification for building JSON HTTP API endpoints for exchanging data between e.g. clients and servers.
/api/<version>/<entity>/<action>/<identifier>
Serving the API under a separate /api
path is optional, it usually helps to route requests correctly. If this rule is applied it should be consistently used for all endpoints.
The version
should be prefixed with a v
like so: v1
. The version is also optional, but same as with the /api
subpath: If it's being used for one endpoint it should be done for all endpoints for the sake of consistency.
The entity describes the business entity that is operated on. It should always be written in plural.
The action describes what action / operation should be applied to the entity. Standard operations are list
, get
, create
, update
, delete
or save
. Special operations that may be customly defined could be e.g. search
, login
, bulk-delete
, ...
The identifier is optional and only required for actions that should be applied to a single entity instance that is identified by this identifier. Usually this is simply an ID of some kind but e.g. for the entity users
it can also be me
for applying actions to the currently logged in user.
GET /api/v1/<entity>/list
Returns a list of the given entity.
GET /api/v1/<entity>/get/<identifier>
Returns the identified instance of the given entity.
POST /api/v1/<entity>/create
Request body contains the new instance. Returns the new instance.
POST /api/v1/<entity>/update/<identifier>
Request body contains the updated instance. Returns the new instance.
POST /api/v1/<entity>/save
A save
endpoint is an alternative to the create
and update
endpoints using an upsert mechanism. If the instance in the request body has an ID an update will be performed. If no ID is given the instance will be newly created.
Next to the standard actions given above, custom actions can be defined, e.g. search
to query instances matching certain criteria, upload
for uploading a file, login
for logging in a user, register
as a create
alias.
The action name should always be a meaningful verb based on the name of the workflow step the endpoint should be used for.
If an error occurs the API should send an apropriate 4xx or 5xx HTTP status code. The response body should contain an error object containing a field message
that gives further information on what happened. Next to the message
field that should always be present, the optional fields code
and i18nMessageKey
can be used. The code
field may contain a custom application specific error code. The i18nMessageKey
should be used for internationalisation and should contain a i18n key that the frontend can use to lookup and display a translation of the error.
Code | Error | Use case |
---|---|---|
400 | Bad Request | Fields missing / wrong fields in request body |
401 | Unauthorized | User lacks access permission for the endpoint |
404 | Not Found | Requested entity instance does not exist |
409 | Conflict | Given data conflicts with existing data, concurrent updates |
413 | Payload Too Large | Payload too large, especially relevant for file upload endpoints, should already be handled by an upstream gateway |
429 | Too Many Requests | Rate limit exceeded, should already be handled by an upstream gateway |
500 | Internal Server Error | Used for basically everything else |
Get all invoices:
GET https://example.com/api/v1/invoices/list
Get invoice with ID 25:
GET https://example.com/api/v1/invoices/get/25
Register new user:
POST https://example.com/api/v1/users/register
Get currently logged in user:
GET https://example.com/api/v1/users/get/me