This is a quick reference sheet of the Complete Guide.
Recommendation | Examples |
---|---|
Plural nouns for resource names, HTTP verbs. | ✅ GET /inventory_items/4 ❌ /get_inventory_by_id/4 |
Singular noun for singleton resource | ✅ GET /status |
Shorten associations | ✅ customers/1/orders?order_id=54&inventory_item=5900 ❌ customers/1/orders/54/inventory_items/5900 |
HTTP Verb / Method | Action |
---|---|
GET |
Read |
POST |
Create |
PUT |
Update (full) |
PATCH |
Update (partial). |
DELETE |
Delete |
Identify resources with SQUUIDs, not Table Row IDs.
Accept
Header preferred:
GET
/inventory_items/4
Accept: application/vnd.livingsocial.v1+json
URI accepted for existing services until they can be re-designed to use Accept
header.
GET
/v1/inventory_items/4
Scheme is semver and ferver based.
- Major.Minor only (e.g.
1.4
). - Never Major version
0
. - Increment Major: multiple breaking changes or significant change in direction or philosophy of API.
- Increment Minor: few breaking changes.
- Never increment for non-breaking changes.
- Retire versions after clients upgrade past it.
- Use
offset
andlimit
: e.g./inventory_items?offset=543&limit=25
- Producer determines field
offset
value is based on,offset
has semantic meaning. limit
has no semantic meaning, simple integer with no relation to resource's data.- Lead the Consumer:
GET /inventory_items?offset=100&limit=25
{
"_links": {
"self": { "href": "/inventory_items?offset=543&limit=25" },
"next": { "href": "/inventory_items?offset=768&limit=25" },
"prev": { "href": "/inventory_items?offset=123&limit=25" }
},
"items": [{ "name": "foo", "desc": "foo to the bar" }, ...]
}
Description | Example |
---|---|
Use simple HTTP params, separate fields for each parameter. | ✅ /offers.json?country_id=2&offer_id=9 |
Do not pass a single param with delimited values. | ❌ `/offers.json?filter="country_id::2 |
Do not use filter or query in the URI. |
❌ /filter_offers.json?country_id=2&offer_id=9 |
Do use sort param. |
✅ /offers.json?sort=city_id |
- Header:
Accept: application/json
- URI extension:
.../cities/nearby/zipcode/1234.json
- For
POST
orPUT
:Content-Type: application/json
- Always use HTTPS for public APIs and internal (AWS) APIs. Internal (IAD) adds a performance hit, use HTTP.
- Pass token with
X-LivingSocial-API-Key
header. - CORS is a thing. Read about it.
- HTTP Status Codes
- Internal API: additional error data in JSON response:
{ "message": "a thing broke", "exception": "[stacktrace/details]" }
- Consumer-Facing API:
{
"errors": [{
"code": "unrecoverable_error",
"title": "The flux capacitor disintegrated",
"details": "Hold on, the end is nigh.",
"user_message": {
"default": "OMG, panic!",
"en-GB": "Keep a stiff upper lip",
"de-DE": "Schnell, schnell!!"
}}]
}
- Use
ls-api_validation
to validate responses in test and production. - Read about Response Envelopes and Hypermedia
- Response Meta Data
GET /offers.json?some=search_query
{
"meta": {
"representation": "tile",
},
"offers": [ ..list of offers... ],
...
}
- Date/Time: RFC 3339 (e.g.
2008-07-31T22:47:31Z-05:00
) - Use UTF-8:
Content-Type: application/json; charset=utf-8
- Currency and Fixed-Point:
{"currency_code": "USD", "value": 1000, "exponent": 2 } => $10.00
{"currency_code": "JPY", "value": 200, "exponent": 0 } => 200 JPY
{ "tax_rate": {"value": 875, "exponent": 2 } } => 8.75%
- Use of XML should be limited to data exchange with the third parties that still use XML.