Tuesday, November 4, 2014

Simple way to compress Web API Response

There are many ways to do Web API Response compression. I particularly like Radenko Zec's solution mostly because it's simple and efficient.

A few steps I did in my project:
  •  Pick your favorite compression tool. I used DotNetZip as Radenko recommended. It gives me close to 85% compression rate for JSON. A CompressionHelper is used as well so that I can easily change to a different compression tool if I want.
  • Implement DeflateCompressionAttribute. Mostly Radenko's code:
    public class DeflateCompressionAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(HttpActionExecutedContext actContext)
        {
            var content = actContext.Response.Content;
            var bytes = content == null ? null : content.ReadAsByteArrayAsync().Result;
            var compressedContent = bytes == null ? new byte[0] : CompressionHelper.Compress(bytes);
            actContext.Response.Content = new ByteArrayContent(compressedContent);
            actContext.Response.Content.Headers.Remove("Content-Type");
            actContext.Response.Content.Headers.Add("Content-encoding", "deflate");
            actContext.Response.Content.Headers.Add("Content-Type", "application/json");
            base.OnActionExecuted(actContext);
        }
    }
  • Add [DeflateCompression] attribute to any WebAPI method needs compression
  • Decompress using standard HttpClientHandler. As our Web API client is expecting objects, we configure HttpClientHandler to decompress response:
            using (var client = new HttpClient(new HttpClientHandler(){AutomaticDecompression = DecompressionMethods.Deflate|DecompressionMethods.GZip}))
            {
                var para = new ServiceParams();
                client.BaseAddress = new Uri(_serviceUrl);
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
                HttpResponseMessage response =
                    client.PostAsync(_servicePath, para, new JsonMediaTypeFormatter()).Result;
                r = response.Content.ReadAsAsync<ServiceResponse>().Result;
            }

1 comment:

  1. Very interesting blog. A lot of blogs I see these days don't really provide anything that I'm interested in, but I'm most definitely interested in this one. Just thought that I would post and let you know.
    cheaterland.com removal

    ReplyDelete