Sometimes we build APIs that have to deal with very expensive requests in terms of performance or bandwidth consumption. An example of this would be if we offer an endpoint which downloads a big pdf document or delivers a high amount of binary data.
In those cases, the consumers of the API would implement a caching mechanism to avoid performing a new request every time. But how do they know how often they need to update the cached content? Even if the caching time has expired, it is possible that the requested content remains unchanged, so it would be inefficient to retrieve the same result over and over again via http calls.
ETag Purpose
The Etag, also known as Entity Tag, is part of the HTTP protocol and is basically a value which corresponds with the current status of a requested resource.
When an API receives a request, it will calculate a hash value based on the response to be delivered. This hash value will be delivered in a HTTP header known as ETag.
The reason why ETag is a very useful tool is because it allows consumers to perform a better management of the cache on the consumer side. They may cache the response to increase performance but at some point, the cache will expire and then a new call will be performed to the server again.
Consumers can use the ETag value and send it on future requests using the header “If-None-Match”. The API (or server) will process the request and calculate the ETag again, but this time it will be compared with the value sent by the client. If it matches, it means that the hash has not been changed, or in other words, the response is the same, therefore the API will deliver a http status code 304 Not Modified.
This way, no response will be sent back to the client, which will lead to bandwidth savings. The client will update the cache as it knows now that the response cached previously is still valid.
Configuration in SpringBoot applications
Since SpringBoot is one of the most used frameworks to develop APIs nowadays, it is very easy to configure the ETag mechanism.
The only thing that needs to be configured is the following Bean in the application context:
@Bean public ShallowEtagHeaderFilter shallowEtagHeaderFilter() { return new ShallowEtagHeaderFilter(); } |
From this moment, the API will start to calculate the ETag for every response and send the value back in the http headers.
To see it in action, this is a very simple example where an endpoint named /ping will return “pong” as a response. This is what happen when we perform the call now:
etag_calculation
As you can see, there is a new header named “ETag”. To check if it is working properly, we can make the same call as before but now sending that value in the “If-None-Match” header:
Voilà, the API just returned the expected http status code 304 Not Modified.