Using ETag to cache responses in NancyFX
Caching data is usually a good idea, especially when creating APIs for mobile clients and the user may pay for each transferred byte. There are many approaches to caching data (I recommend reading this article), in my last NancyFX project I used ETag.
ETag
ETag is a HTTP header that acts as a hash of the data. When the server returns a response, it computes a hash of the data and sends it to the client. When the client requests the data again, it includes the ETag in its request. The server compares the ETag with the hash of the current data and if they match (the data did not change), it returns an empty responses with a HTTP 304 status code.
/// <summary>
/// Gets response with ETag. Returns empty body if ETag matches (no data changes)
/// </summary>
/// <param name="data">Data to match with ETag</param>
/// <param name="model">Model to return</param>
/// <returns>Response</returns>
protected Response GetResponseWithEtag(object data, object model)
{
string etag = Utils.ComputeHash(data);
if (CacheHelpers.ReturnNotModified(etag, null, this.Context))
{
return HttpStatusCode.NotModified;
}
return Response.AsJson(model).WithHeader("ETag", etag);
}
NancyFX impelemntation
To implement caching using ETag in NancyFX I use a method in my base module
There are two parameters in this method, because you may sometimes want to compute the ETag from only a part of the returned model.
Using this method is the really simple
Get["/startlist/{id}"] = parameters =>
{
var startList = _competitionService.GetStartList((int)parameters.id);
var model = new StartListModel() { StartList = startList };
return GetResponseWithEtag(startList, model);
};