Pragmatic RESTful API Design
Chris Dail - @chrisdail
Director, Software Engineering at EMC
- This is a pragmatic approach to REST (not a dogmatic one).
- Ideas here are simply my opinion. I favour user experience and developer sanity over idealogical 'correctness'.
- There is no REST spec or standard (but there is for HTTP)
- Enterprise Software and Products vs SaaS
We love to think our products will solve all customer problems but this is not realistic
- Customer's don't want a product; they want a solution to their problem.
- APIs allow integrating your product into the customer's solution.
- Prevents the feeling of 'lock in'
- Most companies discover they need an API long after v1.0
- Often an afterthough and maybe not given the attention it needs
- Distributed applications, Netflix
- Applications build with small decoupled, self-contained components
- Each component handles a single job
- Components communicate with each other via well established APIs
What Kind of API do I need?
What is REST?
Representational State Transfer
“HTTP based RESTful APIs are defined with these aspects: base URI, such as http://example.com/resources/ an Internet media type for the data. This is often JSON but can be any other valid Internet media type (e.g. XML, Atom, microformats, images, etc.) standard HTTP methods (e.g., GET, PUT, POST, or DELETE)” - Wikipedia
- Web APIs
- Web Services
- Universal language, the Web
- Universally available protocol, HTTP
- Name one programming language that cannot talk to an HTTP server
Elements to a Good API
- Features (I'll assume you have this covered)
- User Experience - Know your user
- Great Documentation
- External Consistency - Does it work like other APIs
- Internal Consistency - Is the API consistent within itself
- Resource Oriented
- Nouns not Verbs
- Pluralize Resources
- Lower case, hypen separated
- Short segments (1-2 words)
- Top level component (when API gets big)
/storage-systems # Storage or Systems is not specific enough
/foo/things # 'foo' component allows multiple /things
- Used for optional parameters, options, search, filter, paging
- Should never be required - Sensible Defaults
- Data format case
- Short (1-2 words)
- JSON First, XML if required
- Case Consistency with all formats
- Keep fields short (1-3 words)
- Handle Collections Differently
Read vs Write data models
- Command Query Responsibility Segregation (CQRS)
- Separate models for read/write
- Example: ID is required for update, but not create
- Example: Password required on create, not part of read
- Self-describing relationships and capabilities
- HATEOAS - Links as part of data
- Link Headers
Link: <https://host/v1/widgets/12/knobs>; rel="knobs"
Paging - Example
Link: </widgets?limit=100&offset=100>; rel="next",
Link: </widgets?limit=100&marker=id123>; rel="next"
- Content Negotiation
Accepts: application/vnd.widgets+json; version="1"
- URL Based
- Easiest to implement for you
- Easiest to implement for users (no headers)
- Most widely used in public APIs
API Change Types
- Additions only. Never remove or rename.
- New fields added to model must be optional
- Renaming or moving API roots or fields
- Deleting APIs
- Adding Required Fields
- Changes to authentication or headers/cookies
- Changes to behaviour
- API version should be a positive integer. Ex: v1, v2, v3
- Not every product release needs an API version
- New version only when backwards incompatible change required
- It is easiest to add versioning concepts in v1!
"message": "Error updating resource",
"details": "Error updating resource with ID 12 because of bla"
Error Format (Validation)
"message": "Validation Error",
"details": "Validation error with the hostname field"
"message": "Hostname field not specified but is required"
- Always use SSL
- Public APIs, use standard SSO like OAuth
- HTTP Basic Auth, Auth Token in cookies/headers
- Browser Explorable
- ETag - Hash/sum in
- Last-Modified -
- Consolidate APIs under single domain
- Support GZip encoding
- Consider an SDK for target developers
- Github and Stackoverflow good examples
- Consider generating documentation
- Inline testing
- What's Wrong With This API
- Name some other poor APIs