ETag vs. included resources


I understand that one can use ETag and If-None-Match to get a resource only if it has changed. But what if the resource in question has not changed in itself, but a related resource has changed, and that resource is included via the include parameter?

Surely the ETag can’t take into account (i.e. change based on) all possible related resources? (Generally, this could at worst include the whole DB). But if a client requests resource A with an included resource from relationship A.B, and uses the If-None-Match, should the client just get a 304 back if A is unchanged even though A.B might be changed?


The presence of the ?include= query param will take care of separating the caches for responses with different custom include parameters. So you don’t need to worry about all possible includes, just actual includes in any given response.

The simple implementation is for the server to compute the whole response and hash that to make the etag. This means you still hit the database, but you avoid transferring the bytes again to the client.

More sophisticated implementations do indeed need to be aware of included resource dependencies if they want to predict exactly whether a given etag is still valid without computing the whole response again.


Are you saying that the ETag is meant to be based on the whole response, not just the primary data?

If so, what about weak ETags, where the content must just be “semantically equivalent”? Does that also include included data?


Yes, ETag is an HTTP concept and covers the whole HTTP response, it doesn’t know about the distinction between primary data and included data.

In my opinion, two requests with different data in the included resources aren’t semantically equivalent.

In HTTP there is often a tradeoff between bundling many resources together (to make fewer requests) vs keeping them separate (to get better caching). I think this is one of those situations.


Thanks! I understand much better now.