Must I return all resource object attributes without a sparse fieldset specified?


#1

Hey folks, must I return all attributes in a resource object when sparse fields are not specified? I’m curious because my entities contain quite a bit of information that’s not absolutely required with each request and I’m stuck in a spot where I’d be specifying many fields for each request.

A couple of thoughts I’ve had when returning a “minimal” set of attributes:

  • When more attributes are requested, prefix fields with a “+” (e.g. fields[article]=+title,+date would add title and date if they aren’t part of the minimal set of attributes)
  • When less attributes are requested, prefix fields with a “-” (e.g. fields[article]=-title would remove title from the response when title is part of the minimal set of attributes)
  • In order to provide the client with a list of available attributes, use meta to describe the entire set of available attributes

Thanks!


#2

Along the same lines, would it be acceptable to overload the meaning of fields to represent views for example? fields[article]=view:simple, fields[article]=view:detailed, fields[article]=view:full or is it better to introduce a custom query param, e.g. view-id instead?


#3

I don’t really see why this is a problem. But one alternative might be to represent different views via multiple resources. For example /articles/{id} for the full data, and /articleSummaries/{id} for the partial data.


#4

@jlangley using different views like that might be an issue with relationships and clients that follow links.

I’ve used a reflection mechanism that uses the meta area to send a list of the request parameters back to the client. This allows sensible defaults to be used and reflected back. *"You didn’t specify what you wanted for parameter foo, so I used parameter foo=bar"

This works very well for paging - you don’t want to send 10,317 records just because the client didn’t bother to set a limit. So a client can specify a limit and get that many results, or not specify a limit and get the default 100 records. (and can see what that limit is in the request param area of the response.)

So for @jgornick’s question, I’d say you could just set a minimal default that’s used unless the client specifies otherwise.


#5

That’s a nice idea.

Can you expand on this?


#6

If /articles/{id} were to return the full article and /articleSummaries/{id} return only a subset of attributes…
Then which does eg /review/{id} .relationships.article link to?

Does the client need to be explicitly programmed with the two routes?
Does it need to manually rewrite a link from one to the other?

In another point of view, all the routes and responses in an API are like a connected graph. (graph nodes are API routes, graph connections are relationships and other links)
I think that having two routes as described will result in a graph that’s not fully connected, and result in confusion.


#7

It’s a good question.

Going back to the internet being full of resources that are interlinked, I think a summary is a different resource and, as such, it must be treated as such.

Each domain needs a different level of linking. Very few domains require a fully connected graph and that might seem confusing but if you’re designing the domain to be used in a certain way then you will have sparse graphs.

I would have /articleSummaries/{id}. Each summary links back to its parent. The fact that the {id} is the same is coincidental - the client is not expected to build a URI.

For reviews, you must ask yourself “how do I want the client to use the resource?”. Do you want to go to /reviews/{id} directly from a /articleSummaries/{id}? If so, then include a relationship. If you require the client to load the full article first then do not include the relationship link. Or include both relationships! For this particular domain example, I probably would include both.

That means that the client could do this:

GET /reviews/0?include=articles,articleSummaries

Which is silly but I would rather have the power there and hope the client author does something sensible.

In the domain I use at work, sparse linking is used to steer the user through “the right way to use the system”, which is part of the power of hypermedia as they can do that without documentation.


#8

I’d imagined it would link to the article, to link to an article summary you would have an articleSummary relationship. A review could of course have links to (i.e. relationships for) both the article and its summary (I see @brainwipe has had the same thought).

Yes, but that doesn’t worry me. The alternative is that client needs to be explicitly programmed to include relationships or filter fields. It might be that no client wants both representations, but rather different clients want different representations.

Because I’m a fan of hypermedia I wouldn’t do this, but you could.

I have seen other solutions based around using the Prefer header to negotiate the level of detail, but that has other drawbacks.

I don’t see that this follows. But probably (again similar to the suggestion from @brainwipe) I would have two-way links between an article and its summary.