Description
I perennially run into difficulty trying to draw a line around which properties it's reasonable for a resource to return. I'd love it if you could address that in your docs, or talk about how you settled these issues when building your UI on top of the REST API.
Consider a system with users and orgs. I'd assert that it's reasonable for the UI to present a table of all the orgs, with some vital stats about each. If the table must show the user count for each org, there are two obvious solutions for acquiring the user count:
- add
userCount
to the org resource
curl https://service.com/orgs
[
{
"id": "01234567-89ab-cdef-0123-456789abcdef"
"name": "SPECTRE",
"userCount": 21
},
// ... additional org descriptors
]
- force clients to fetch the list of users for each org and count them
// repeat for each record returned by the org resource
curl https://service.com/orgs/{org_id}/users
[
{
id: "7e876304-bcd9-4ce6-9119-126be52f4486",
username: "eblofeld",
"created_at": "1908-05-25T12:00:00Z",
"updated_at": "1981-06-24T13:00:00Z",]
},
// ... plus 20 more user descriptors
]
Approach 1 can lead to death by a thousand cuts: the server code backing each resource grows with every new property required by UI, increasing CPU cost but reducing API traffic. And per your versioning strategy, the only way to withdraw support for any such property is to cut a new version (while maintaining the old version).
Approach 2 results in both client and server doing lots of work that neither is really interested in; in this case, the content of each user descriptor is discarded, because the only data needed is the length of the array. For collections with many members or whose members have many properties, you also end up with heavier payloads. It also results very quickly in a huge number of requests: 1 + n * c
, where n is the number of rows returned and c is the number of "vital statistics" that aren't part of the base response.
I'm reluctant to draw the line based on the underlying database schema, since that feels like an implementation detail that ought to be abstracted at or by this layer.
Your comments are very much appreciated.