They focus on security and high availability. Free for devs.
- Latency caching?
What're the things you can use to make your life easier?
HATEOAS - Hypermedia As The Engine Of Application State. The API and all info is self-contained in the data sent to and from the server - no out-of band info. Basically, you shuldn't need to go elseqhere or look up docs.
Fielding's Requirements:
- no fixed names/hierarchies
- dynamically typed
- communication protocol independent (not just HTTP)
- media type centric
- zero out-of-band knowledge - you should be able to browse the entire API without needing look at any docs, resources should link to each other
Most companies violate the zero out of band knowledge requirement.
- Nouns, not verbs!!!
- Coarse grained, not fine-grained
- Architectural-style for use-case scalability
- Collections Resource
Eg: /applications
- make it a plural noun!
Eg: /application/thing123
- this is an individual thing in your applications collection
How do we dfine behaviour?
Duh! The HTTP verbs! But: don't use HTTP verbs 1:1 with CRUD ops (PUT and POST don't quite fit in). PUT can create, POST can modify.
PUT should be able to create a resource if it doesn't yet exist at a canonical location, ie, you'd define the ID instead of letting the server do it in the case of POST. PUT is idempotent, so you need to send every field in a resource (UNLIKE PATCH). In TLS/1.3, GET MUST BE IDEMPOTENT since the server can retry. Idempotentcy is very important because of HTTP caching.
POST can create, but don't allow creation to the canonical namespace. Also, you extremely need to send back a 201 Created
with the LOCATION HEADER SET TO THE URI OF THE NEW RESOURCE!!!!! This is super important, since following creation, that's the canonical URI for that resource. POST can also update a resource using partial data because IT IS NOT IDEMPOTENT!
These are really just a format specification and a set of parsing rules, ie:
application/ion+json
- it's in JSON, and follows the ion
spec (for example), so follow the ion parsing rules.
Intuitive codification of Roy Fielding's spec.
Resources:
Consider this JSON object:
{
"meta": { ... }, // new field that exists in every request!!
"firstname": "Bob",
"brithdate": "1993-26-06",
}
Esentially is a JSON object with a meta
object. Imagine some JSON like,
{
"meta": { ... },
"items": [],
}
The meta field will have information like items in the collection, max lenght, etc.
- distributed hypermedia is paramount
- every accesible resource has a canonical unique URL
- these replace IDs (IDs exist but are opaque)
- critical for linking
How do you do this in JSON? XML has the XLINK
spec, but JSON has nothing, but we should add it in the meta
field.
// GET /accounts/xyz123
{
"meta": {
"href": "https://api.domain.com/accounts/xyz123/groups",
"rel": ["collection"],
},
"name": "Bob",
"birthDate": "1993-26-06",
}
You ever find yourself needing to read the docs to figure out how to POST to your favourite API? That's bad, since it requires out of band knowledge. HTML knows how so... why don't APIs?
Use Forms in the meta field!
{
"meta": { "href": "https://foo.io/users", "rel": ["create-form"], "method": "POST"},
"items": [
{"name": "login", "required": true, "label": "Username or Email"},
{"name": "password", "secret": true, "required": true, "label": "Password"},
]
}
- not needed => REST != RDBMS (schemas aren't necessary for browsers/HTML)
- forms do the same thing and are more flexible/powerful
- make it as easy as possible for a user to use/browse your API
- the server should support multiple formats depending on the client, ie, send JSON for
application/json
, HTML fortext/html
, plaintext fortext/plain
. - versioning: do it the media-type from the beginning, or at the very least, make sure your URLs will work the same today as they will 2 years in the future. people like to save URLs in databases
- resource extension:
/applications/abc123.json
- don't do it, there's anAccept
header for a reason. Obviously this isn't horrible and works in some cases, but consider using Content Negotiation - just use
camelCase
- dates and times: lol. please use ISO 8601 and USE UTC time! (make your server generate UTC time).