Nancy Rest Services – GZIP IT!

When dealing with JSON data, and you dealing with large result sets, say larger than a 1MB or so, it will definitely be feasible in many situation to zip the data before sending it to your client application.

The first step is to add zipping to the pipeline that Nancy uses, we then check that the content type returned in the response is JSON and we check that the client can accept the encoding of GZIP.

public static void AddGZip(IPipelines pipelines)
        {
            pipelines.AfterRequest += ctx =>
            {
                if ((!ctx.Response.ContentType.Contains("application/json")) || !ctx.Request.Headers.AcceptEncoding.Any(
               x => x.Contains("gzip"))) return;
                var jsonData = new MemoryStream();

                ctx.Response.Contents.Invoke(jsonData);
                jsonData.Position = 0;
                if (jsonData.Length < 4096)
                {
                    ctx.Response.Contents = s =>
                    {
                        jsonData.CopyTo(s);
                        s.Flush();
                    };
                }
                else
                {
                    ctx.Response.Headers["Content-Encoding"] = "gzip";
                    ctx.Response.Contents = s =>
                    {
                        var gzip = new GZipStream(s, CompressionMode.Compress, true);
                        jsonData.CopyTo(gzip);
                        gzip.Close();
                    };
                }
            };
        }

Perfect, now what we want to do is also, is in the CLIENT application calling the rest service, we need to add a header to the request so the server knows is supports GZIP:
Accept-Encoding: gzip

So, we add this code to the client.

Request sent by client.

protected WebRequest AddHeaders(WebRequest request)
        {
            request.Headers.Add("Accept-Encoding", "gzip");
            return request;
        }

Response processed by client.

if (((HttpWebResponse)response).ContentEncoding == "gzip"
                    && response.ContentType.Contains("application/json"))
                {
                    var gzip = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress, true);
                    var readerUnzipped = new StreamReader(gzip);
                    Response = Deserialize(readerUnzipped);
                }
                else
                {
                   Response = Deserialize(reader);
                }

Implement whatever deserializer you want, and then make sure you close the stream, reader.close 😉

Server No GZIP

GZIP-With Compression

Advertisements

One thought on “Nancy Rest Services – GZIP IT!

  1. Nice, saved me remembering how to do this 🙂
    Need to fix your code example though, it’s all escaped which makes the old cut and paste more difficult 😉

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s