DEV Community

Cover image for The Vary HTTP header
Nicolas Fränkel
Nicolas Fränkel

Posted on • Originally published at blog.frankel.ch

The Vary HTTP header

I try to constantly deepen my knowledge of HTTP and REST. Recently, I stumbled upon the list of all registered HTTP Headers. This post is dedicated to the Vary HTTP Header.

The problem

Two years ago, I wrote about web resource caching server-side. The idea is to set up a component between the client and the upstream to cache previously computed results to avoid overloading the latter. Depending on your infrastructure and requirements, this component can be a reverse proxy or an API Gateway. HTTP offers the Cache-Control header to customize the different aspects of caching, e.g., the time the server holds the resource in cache before it considers it stale. I used plugin configuration in the above post, but you can also delegate to Cache-Control.

Now, imagine the following scenario. You request a resource, e.g., GET /book/1 and get the result:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "title": "Notre-Dame de Paris"
}
Enter fullscreen mode Exit fullscreen mode

The request succeeds; the result is cached. Now, I request the same resource, but because my code works around XML, I set the Accept header to application/xml. Unfortunately, the server returns the cached JSON resource, which differs from what I asked and probably utterly breaks my code.

The problem is that the cache key has a single dimension, the URL, by default.

The solution

We need a configurable multi-dimension cache key. As you can probably guess by now, that's the role of the Vary header: it explicitly lists all dimensions of the cache key. In the example above, the upstream would communicate the additional cache key with the following:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Language: en
Vary: Accept


{
  "id": 1,
  "title": "Notre-Dame de Paris"
}
Enter fullscreen mode Exit fullscreen mode

Instead of a single cache entry per URL, we now have one per MIME type/URL combination. Note that it's up to the caching component to use this information.

Another common request header is Accept-Encoding, which usually specifies which compression algorithms the client can accept. Encoding is another possible cache key. The specification allows specifying multiple cache keys:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Language: en
Vary: Accept, Accept-Encoding


{
  "id": 1,
  "title": "Notre-Dame de Paris"
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

I've described the Varyresponse header in this post. As soon as you configure caching, you must consider possible cache keys and use the Vary header accordingly.

To go further:


Originally published at A Java Geek on May 5th, 2024

Top comments (2)

Collapse
 
ervin_szilagyi profile image
Ervin Szilagyi • Edited

Hi @nfrankel,

Great article.
Would you be kind to fix the typo from the first sentence of the post? :)

Collapse
 
nfrankel profile image
Nicolas Fränkel

Thanks for the feedback, it's fixed.