One of the key things when testing API’s is the caching of response. Caching can have a lot of positive or even negative impact on the overall performance of a web page.
So a lot of times, my api testing test cases involves testing around how the caching has been done through the API’s.
That is why one of the key things to keep in mind is the
Cache-Control HTTP header when testing the API’s, and make sure you include this header when you’re designing the test cases/scenarios for an API test or an API-UI integration test.
Cache-Control is an HTTP header, which contains directives – in case of both request and response – that define how the caching needs to be done in the browser cache and the shared cache – for e.g a CDN.
Some key points for the Cache-Control directives
- The directives are not case-sensitive, although lowercase is recommended.
- There can be multiple directives, which needs to be comma-separated.
- Their are directives which may have optional values.
There is a whole list of cache-control directives that you can find at the MDN url -> Link
Let’s discuss a couple of important ones –
max-age: When the api response is recieved, then the response is FRESH. In due time it may become STALE. You can read here about the freshness or staleness of response.
The format of the directive is
Cache-Control: max-age= N
The max-age directive is used to indicate the freshness of the response. The max-age directive indicates that the response remains fresh until N seconds after the response is generated.
Now the last word is important – generated, and not recieved. So, this directive measures the freshness of the response w.r.t the response generated by the origin server. So if the other cache(s) — on the network route taken by the response — store the response for 100 seconds (indicated using the Age response header field), the browser cache would deduct 100 seconds from its freshness – so it would now be N-100.
no-cache: This directive is almost misunderstood most of the time. The primary objective of this directive is not to specify to not cache the response.
The no-cache directive indicates that the response can be stored in cache, but that the response must be validated with the origin server before it is used again. This has to be done even if the connection with the origin server is closed.
no-cache doesn’t mean there is never caching, but rather that the user agent has to always ask the server if it’s OK to use what it cached.
The format of the directive is
If you want caches to always check for content updates while reusing stored content, no-cache is the directive to use. It does this by requiring caches to revalidate each request with the origin server.
- must-revalidate – This directive means that the stored cache can be re-used if the cache is fresh. If it is not fresh then response must be re-validated with the origin-server before being used.
must-revalidate is generally used in conjunction with the
max-age directive – meaning that the cache has to be revalidated after the given N max-age, like this
Cache-Control: max-age=604800, must-revalidate
- no-store – This means that you do not have to store cache of any kind ( private or shared) for this kind of response.
The no-store header, prevents the data from being stored outside of a session, in which case it simply isn’t available for a history mechanism to use.
With no-store, if the user ends his session by navigating to another domain and then goes back, the only way for browser to know what to display is to get the initial page again from the server.
The format of this directive is
Cache is a powerful mechanism which can have either a positive or negative impact on the overall performance of your application , based on how you configure and use it. So when testing applications, it is a key point to include tests for the cache – whether the are being stored on a browser machine or on proxy or CDN.
I hope this helps someone who is trying to understand the various headers that we see in the apis that we test. Please leave a comment if you have to add something or if you want me to post on some other topic.