I am designing a REST API that will be used by several clients to query a data repository. I am anticipating that these clients will have different needs regarding the amount/level of detail of the responses.
Let's say I can query a collection of books. A book might potentially have lots of attributes (more than any single client might be interested in), maybe even subresources, and a client might request a large number of books, leading to a response body that is larger than required.
Therefore I am looking into ways of optimizing response size. The idea is to give the API client some means of specifying how much detail should be included in the response.
I would be interested to learn how this problem has been solved before; which mechanism worked well in practice and which didn't, which API design is particularly RESTful and which isn't, and so on.
A few ways I can think of how a client could possibly specify desired level of detail for the response:
Using either the GET
or HEAD
HTTP method / verb. The former would return all details, the former only a subset.
This approach only allows us to distinguish between two levels of detail, so it is of limited use.
Having a query string parameter that specifies (by name) which properties/attributes should be returned in the response. For example:
GET /books?include=title,author,publisher,...,preview
This offers almost unlimited flexibility, but this very flexibility might be difficult to actually implement and deal with (on both the client and server side).
Using different media types (one distinct media type per level of detail), selected via the Accept:
header.
I don't really want to go down that route. I am not sure media types are appropriate for this purpose, and the world probably doesn't need more custom media types anyhow.
Using the profile
relation / media type parameter. This seems a little better (no additional media types are required), but I am still unsure whether media types are the right method for selecting the "what" (content) of a response. They seem more appropriate solely for specifying the "how" (format) of the response.
For book collections (/books?publishedIn=1980s
), only a small subset of all available data is returned, most importantly a href
for each book that can be queried to get the full data about a single book.
This approach has at least two problems:
What attributes are included in collection responses besides the href
links? Ideally, there is just enough additional data to satisfy most clients; otherwise...
Clients will have to perform lots of additional queries (one per book) to collect all the data that they need.
There are possibly more strategies for selecting the desired level of detail. I am interested to learn what works well in practice, without compromising RESTfulness too badly.
I think it depends mostly on how much flexibility you want to give to your API clients.
If you know the different uses of your data, you might want to define some available formats that your API can return.
For example, using this structure:
GET /books (with a default format if nothing is specified)
GET /books/minimal
GET /books/full
GET /books/otherformat
Note that this could also be using this URL structure if you don't want to duplicate your endpoints:
GET /books?format=minimal
However, in either case, this forces you to know exactly what data your clients will need or want at any given time.
I would not rely on media types as this might be more confusing for users than other more standard way of working with REST APIs.
[EDIT]
Also, should you decide to specify the whole list of fiends to return and find out that GET requests are not sufficient, you could refer to this post for an alternate way using POST requests