Caching webservice with varnish

Published the Wednesday, February 21, 2018 at 7:44 PM Keywords: Varnish Web service REST HATEOAS URI

I recently had to find a way to cache a webservice anwsers.

The webservice is a RESTfull API serving as a gateway between a private HATEOAS API and a client generating more than 500 000 requests a day.

The first surprise is that if your well educated client, sending you a header Authorization: Bearer, will not be cached by default by Varnish !

Let's force back the standard behaviour with this header for our webservice uri prefix:

sub vcl_recv {
	# Force cache response even with req.http.Authorization set
	if (req.http.Authorization) {
		if (req.url ~ "^/webservice/uri/prefix/") {
			return (lookup);
		}
	}
}

This has security implication, because anyone allowed to request varnish will be able to retrieve a cached result without authentification.

It is important to validate the Authorization header value before serving the result from cache.

Now, our webservice has three possibles answers :

Let's cache our results depending on the reponse code:

sub vcl_fetch {
       if (req.url ~ "^/webservice/uri/prefix/") {
		if (beresp.status == 404) {
			set beresp.ttl = 7d;
		}
		if (beresp.status == 410) {
			set beresp.ttl = 7d;
		}
		if (beresp.status == 200) {
			set beresp.ttl = 24h;
		}
	}
}

With this configuration, we divided by 5 the quantity of request on our gateway from the client who was not able to cache our result himself.