Notes from designing a beautiful REST&JSON API.
Two types of Resource
/accounts
)/accounts/123
)Behaviours
Media Types are set in your request header and response header tells you what the server is giving you.
Accept
headerContent-Type
headere.g:
application/json
application/foo+json
*/*
https://api.example.com
rather than https://www.examle.com/service/api/public/rest
In the URL https://api.example.com/v1
or in the header request: application/json;application&v=1
Use CamelCase not under_scores!
All resources should have createdAt
field. Use ISO8601 standard, and use UTC so you don't have to worry about the local timezones. Use Carbon to manage date functions.
Header values are comma delimited in order preference:
Accept: application/json, text/plain
Adding an extension will override the Accept
header
/application/abc123.json /application/abc123.csv /application/abc123.txt
415 - Unsupported media type
Always return a href to the resource
{
href: 'https://api.example.com/v1/account/123',
name: 'joe blogs'
email: 'joe@example.com'
}
GET /accounts
GET /accounts/123
GET /accounts/123?expand=directory
Collection resources should support parameters
e.g /accounts?offset=50&limit=25
and return first,next,last urls:
{
"href": 'https://api.example.com/v1/account/123',
"offset": 50,
"limit": 25,
"size": 250,
"first" : {
"href": 'https://api.example.com/v1/account/123?offset=0&limit=25'
},
"next" : {
"href": 'https://api.example.com/v1/account/123?offset=75&limit=25'
},
"last" : {
"href": '...'
},
"items": [
{
name: 'joe blogs'
email: 'joe@example.com'
}
]
}
Use href links to account and group details:
"items": [
{
name: 'joe blogs'
email: 'joe@example.com'
account: {
"href": 'https://api.example.com/v1/account/123'
}
}
]
Be as descriptive and give as much information as possible
{
"status": 409,
"code": 12345,
"property": ""
"message": ""
"developerMessage" : ""
"moreInfo": ""
}
status
is HTTP statuscode
is your internal codemessage
is a standard field and should always be includedIf you want users to use a FORM to interact with your API rather than Curl etc, attach the method at the end of the form URL.
For example:
POST /accounts/xyz123?_method=DELETE
(Laravel does this)