/ HTTP, REST, RESTFUL

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"
}

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"
}

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"
}

Conclusion

I’ve described the Vary`response 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:

Nicolas Fränkel

Nicolas Fränkel

Nicolas Fränkel is a technologist focusing on cloud-native technologies, DevOps, CI/CD pipelines, and system observability. His focus revolves around creating technical content, delivering talks, and engaging with developer communities to promote the adoption of modern software practices. With a strong background in software, he has worked extensively with the JVM, applying his expertise across various industries. In addition to his technical work, he is the author of several books and regularly shares insights through his blog and open-source contributions.

Read More
The Vary HTTP header
Share this