TL;DR of https://pages.apigee.com/rs/351-WXY-166/images/ebook-2013-03-wad.pdf
[EDIT 04/01/2021] https://docs.apigee.com/files/Web-design-the-missing-link-ebook-2016-11.pdf
- Nouns are good; verbs are bad
- keep simple things simple
- keep your base URL simple and intuitive
- 2 base URLs per resource
/dogs
for collections;/dogs/1234
for itemPOST /dogs
create a new dogGET /dogs
list dogsPUT /dogs
bulk update dogsDELETE /dogs
delete all dogsPOST /dogs/1234
ErrorGET /dogs
Show BoPUT /dogs
If exists update Bo; else ErrorDELETE /dogs
delete Bo- use plural nouns
- be consistent
- concrete names are better than abstract
- simplify associations
GET /owners/5678/dogs
get all dogs belonging to specific ownerPOST /owners/5678/dogs
to create a new dog for that owner- you should not need deeper URL than
/resource/identifier/resource
- sweep complexity behind the '?'
GET /dogs?color=red&state=running&location=park
get all red dogs running in the park
- handling errors is very important piece of the puzzle
- test-first and tdd -> learn to write code through errors
- use HTTP status code, but the common ones
- 200 - OK
- 400 - Bad Request
- 500 - Internal Server Error
- then make messages in the payload as verbose as possible
- add a link in description to more information about the error
- never release an API without a version
- make the version mandatory
- a 'v' prefix on the left in the URL:
/v1/dogs
- use a simple ordinal number (v1, v2, ...)
- in the URL: if it changes the logic you write to handle the response
- in the header: if it does not change the logic for each response, like OAuth information
- these for example, all represent the same resource
/dogs/1 Content-Type: application/json
/dogs/1 Content-Type: application/xml
/dogs/1 Content-Type: application/png
- but the code to handle the responses would be very different
- there is no question the header is more correct and it is still a very strong API design
/dogs?fields=name,color,location
returns only needed fields for developer/dogs?limit=25&offset=50
returns the 25 rows starting at 50s row
- user verbs not nouns:
/convert?from=EUR&to=CNY&amount=100
- Google Data:
?alt=json
- Foursquare:
venue.json
- Digg:
Accept: application/json
or?type=json
- recommandation:
/dogs/1234.json
- use json as default format
var myObject = JSON.parse(response); var timing = myObject.createdAt;
- json/javascript conventions
- use resourcefull API:
/dogs?q=red+running+park
- multiple resources:
/search?q=fluffy+fur
- return specific format:
/search.json?q=fluffy+fur
or/search.xml?q=fluffy+fur
- assuming your top-level domain is
teachdogrest.com
- API gateway should be:
api.teachdogrest.com
- the developer portal should be
developers.techdogrest.com
- redirect is your friend:
- api -> developers (if from browser)
- dev -> developers
- developer -> developers
- use OAuth - OAuth 2.0
- Create a brown dog named Al
POST /dogs
name=Al&furColor=brown
// Response
200 OK
{
"dog": {
"id": "1234",
"name": "Al",
"furColor": "brown"
}
}
- Rename Al to Rover - Update
PUT /dogs/1234
name=Rover
// Response
200 OK
{
"dog": {
"id": "1234",
"name": "Rover",
"furColor": "brown"
}
}
- Tell me about a particular dog
GET /dogs/1234
// Response
200 OK
{
"dog": {
"id": "1234",
"name": "Rover",
"furColor": "brown"
}
}
- Tell me about all the dogs
GET /dogs
// Response
200 OK
{
"dogs":
[{"dog": {
"id": "1233",
"name": "Fido",
"furColor": "white"}},
{"dog": {
"id": "1234",
"name": "Rover",
"furColor": "brown"}}...],
"_metadata":
[{"totalCount": 327, "limit": 25, "offset": 100}]
Delete Rover :-(
DELETE /dogs/1234
// Response
200 OK
Read more: https://blog.apigee.com/taglist/restful
- Your product manager is a key member of your API team
- "Use the façade pattern when you want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve."
- How-to:
- Design the ideal API. The API design should be self-consistent.
- Implement the design with data stubs.
- Mediate or integrate between the façade and the systems.
[Author: Brian Mulloy, Apigee]