A 'Hypermedia API' is one in which the architecture of the API is similar to the architecture of the world wide web.
- Designed for scale. This architecture has been proven over the last 20 years, and powers the largest information system ever created.
- Change tolerant. Forwards and backwards compatibility are encouraged through decoupling of components
- Component encapsulation enables building bigger systems out of smaller ones.
- If you need sub 100ms latency, this is not your architecture.
- Caching is used heavily. "There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors."
- A favoring of text formats means that individual messages may not be as small as binary formats.
Server implementation notes
The two fundamental rules:
1. Respect HTTP
2. Use a hypermedia media type
Obey the spirit of RFC 2616, not the letter. Read the spec rather than blogs. It's fairly readable.
Don't trust what you think you know, it's probably wrong. Or at least, not 100% accurate. Example: PUT requires a full replacement representation, not just a partial one. PUT can also be used to create resources, it's an 'upsert' not an 'update.'
For clarifications on many issues, check out httpbis.
If you're interested in the reasoning behind creating the protocol, check out Fielding's dissertation. Sometimes, knowing first principles can help explain 'odd' design decisions.
Hypermedia media types
You have two major options for a hypermedia type.
- Use an existing type
- Build your own
Use an existing type
Build your own
Two paths: Make a custom type, or use the profile link relation.
If you'd like to make a custom type, read Building Hypermedia APIs in HTML5 and Node. Building a custom type is just as much art as science.
To add hypermedia flavor to a type (commonly JSON), check out this Internet Draft: The 'profile' Link Relation Type
Client implementation notes
- Implement the media type, not a specific server's responses.
- Only rely on what's in the media type definition, nothing else.
- If possible, make two services that serve up the type and test your client against both.
- Be flexible: don't rely on structure too much. Use
//in xpath, for example.
- Implement local caching. The most efficient request is one that never uses the network.