Showing posts with label Web API. Show all posts
Showing posts with label Web API. Show all posts

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;
            }