This is meant to be an ongoing post updated as I make my mind on different issues about API design.
| REST | CRUD |
|---|---|
| POST | CREATE |
| GET | READ |
| PUT | UPDATE |
| DELETE | DELETE |
Authentication
- OAUTH 2.0
- Access token delivered in HTTP Basic Auth username field is also a good method to transfer access credentials.
- For JSONP
?access_tokenquery parameter can be used, but it is a security risk because access credentials will be saved in web server logs - In any case, HTTPS must be the only way to access the API and under no circumstances plain text data communication should be allowed.
Resources
- Verbs are bad
- Nouns are good, use plural nouns as resources
- The only verbs used are post, get, put and delete
- Anything more complex put after the
?
/dogs?color=black&state=running&location=earth
| Example | POST | GET | PUT | DELETE |
|---|---|---|---|---|
| dogs | create new dog | list dogs | bulk update dogs | delete dogs |
| dogs/1234 | error | get dog id 1234 | update dog 1234 | delete 1234 |
| owners/321/dogs | create dog for owner | gets dogs of owner | update dogs of owner | delete dogs of owner |
| owners/321/dogs/1234 | error | get dog 1234 of owner 321 | update dog 1234 of owner 321 | delete dog 1234 of owner 321 |
Format
- JSON only
I never liked XML, never was very good at it. So although I am usually tempted to add a format option to the api and generate output in JSON and XML, I am going to skip XML from now on and use JSON as the default and only format. - Pretty json output and gzip compression by default.
- No envelope for returned attributes by default. If envelope is needed api specifications can provide an
?envelope=trueoption in which case meta and response attributes can be returned in an envelope. - Although a lot of smart people say
camelCaseI thinksnake_casemakes for better readability.
Versioning
- Mandatory Versioning
- Versions in URL api.example.com/v1/dogs
- If needed subversions can be provided in the header
Return Codes
- Return correct HTTP status codes.
200 – OK
201 – Resource Created
401 – Unauthorized - Optionally provide additional internal status codes and links to documentation / discussion pages.
{
"status": 401,
"message": "Unauthorized",
"code": 20003,
"more_info": "http://location/docs/errors/20003"
}
- Optionally allow ?suppress_http_status_codes_and_use_envelope=true to suppress HTTP status codes and always return 200 – OK with additional status information. We use envelope here to prevent collision of status and error information with other attributes.
Filtering, Sorting, Searching
- /dogs?color=black – Return only black dogs
- /dogs?color=black&sort=-age – Return only black dogs and sort by age in descending order
- /owners/123/dogs?color=black – Return only black dogs of owner 123
- /dogs?q=rocky – If available, full text search
- /search?q=rocky – Global search across resources, use
searchas a reserved word
Pagination
- /dogs?limit=25&offset=50
In my opinion, limit and offset should be the preferable choice here, mostly because most open source databases support limit and offset for queries. - /dogs?count=25&start=50
For some reason I have a problem understanding limit and offset. I have to mentally stop and think for a second to understand what it means. So I would like limit/count and offset/start to be used interchangeably. X-Total-CountHTTP header for the total count.- Should already have a reasonable default. (i.e. limit=10, offset=0)
Partial Response
All of the resource attributes are not always needed and giving the client ability to ask for a subset of the fields is good design.
- /dogs?fields=name,color,location
- /owners?fields=name,dogs(name)
Other Considerations / Not Decided
- Caching
- Binary Data
- Links
- HATEOAS
- Rate Limiting
Design Tools
- I have decided on using RAML for API design and documentation. I looked at a lot of different things (Swagger, API Blueprint, XML, etc.) To be honest API Blueprint seems very mature and I like Markdown but still my decision was towards RAML. So that’s that.
References
- Apigee videos and slides are great, and the way @landlessness looks at this stuff is very good
API Design – Second Edition
API Design – Third Edition
Restful API Design Nouns are Good, Verbs are Bad - Apigee Console is a great way to explore API designs
- Vinay Sahni’s Best Practices for a Programatic Restful API has very through and well thought information in my opinion.
- API Design: Do You Swagger, Blueprint or RAML?
- https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
- RAML: RESTful API Modeling Language
- raml2html