Filtering, Sorting, and Pagination
Filtering
―LHS Brackets
GET /items?price[gte]=10&price[lte]=100―RHS Colon
GET /items?price=gte:10&price=lte:100―Search Query Param
GET /items?q=title:red chair AND price:[10 TO 100]Pagination
―Offset Pagination
GET /items?limit=20&offset=100, returns the 20 rows starting with the 100th row―Keyset Pagination
GET /items?limit=20&created:lte:2018-01-20T00:00:00It uses the filter values of the last page to fetch the next set of items
―Seek Pagination
GET /items?limit=20&after_id=20Extension of Keyset paging. By adding an after_id or start_id URL parameter
Sorting
―Multi-Column Sort
GET /users?sort_by=desc(last_modified),asc(email) GET /users?sort_by=-last_modified,+emailThe good API design is a critical component for your Developer Experience (DX). API specifications can outlast many underlying server implementations which require thinking about future use cases for your API.
https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination/#
Getting, creating, updating or deleting multiple resources in one API call
―Working with a single resource
Creating a resource
Getting a resource
Updating a resource
Replacing or creating a resource
Deleting a resource
―But why explaining all that? I want to work with multiple resources!
―Same action on resources of the same type
A request containing multiple resources
Create multiple resources
Update or replace multiple resources
Get or delete multiple resources
―A response containing responses
The 207 (Multi-Status) status code provides status for multiple independent operations:
―Two levels of error
In that case, we must be aware that there are two types of errors, the one concerning one or more of the resources and the one concerning the multiple request itself.
―Single and multiple creations with the same endpoint
Use a list/map for both case
Accept both a list/map and single object
―Different actions on resources of the same type
―Different actions on resources of different types
Best Practices for Designing a Pragmatic RESTful API
―An API is a user interface for a developer - make it pleasant
―Use RESTful URLs and actions
Use plural
―Use SSL everywhere, no exceptions
―An API is only as good as its documentation - so have great documentation
―Version via the URL, not via headers
―Use query parameters for advanced filtering, sorting & searching
―Provide a way to limit which fields are returned from the API
―Return something useful from POST, PATCH & PUT requests
―HATEOAS isn't practical just yet
'Hypermedia As The Engine of Application State' (say return the data and links to other relevant endpoints related to the current endpoint)
―Use JSON where possible
―You should use camelCase with JSON, but snake_case is 20% easier to read
―Pretty print by default & ensure gzip is supported
Since the cost of pretty-printing is relatively small, it's best to pretty print by default
―Don't use response envelopes by default
―Consider using JSON for POST, PUT and PATCH request bodies
―Paginate using Link headers
Link: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next", <https://api.github.com/user/repos?page=50&per_page=100>; rel="last"―Provide useful response headers for rate limiting
―Auto loading related resource representations
―Use token-based authentication, transported over OAuth2 where delegation is needed
―Include response headers that facilitate caching
―Define a consumable error payload
―Effectively use HTTP Status codes
Common disagreements over REST API design
―“If the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API.”
―PUT vs POST: Which should you use for creating new resources?
If you know the location of the resource then use PUT, otherwise, POST is probably more appropriate.
―Doing PATCH “properly”
―The correct way of doing Authentication: stateless
―“A REST API must not define fixed resource names or hierarchies. Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs.”
―REST and CRUD are not the same things.
―“A REST API should not be dependent on any single communication protocol”
―Doing versioning 'right': putting it on the URI, using a custom request header or adding it to the HTTP Accept header.
REST cookbook
The RESTful cookbook website is inspired by the puppet cookbook from Dean Wilson, who created cookbook recipes on how to deal with some of the issues people are facing over and over again when using the Puppet Configuration management tool. This site, however, is about dealing with issues and questions people are facing over and over again when trying to create RESTful APIs.
―Basics
- How do I let users log into my RESTful API?
- Caching your REST API
- How do I version my REST API?
- What is HATEOAS and why is it important?
- What is the code-on-demand constraint?
―HTTP headers
―Mediatypes
HTTP API Design Guide
This guide describes a set of HTTP+JSON API design practices, originally extracted from work on the Heroku Platform API.
This guide informs additions to that API and also guides new internal APIs at Heroku.
It’s also of interest to API designers outside of Heroku.
The goals here are consistency and focusing on business logic while avoiding design bikeshedding.
Looking for a good, consistent, well-documented way to design APIs, not necessarily the only/ideal way.
It is assumed you’re familiar with the basics of HTTP+JSON APIs
This guide will not cover all of the fundamentals.
It is available for online reading and in multiple formats at gitbook.
―Foundations
- Separate Concerns
- Require Secure Connections
- Require Versioning in the Accepts Header
- Support ETags for Caching
- Provide Request-Ids for Introspection
- Divide Large Responses Across Requests with Ranges
―Requests
- Accept serialized JSON in request bodies
- Resource names
- Actions
- Use consistent path formats
- Downcase paths and attributes
- Support non-id dereferencing for convenience
- Minimize path nesting