Web API compression is very important to improve ASP.Net Web API performance. Data travels through the network in packages (data packets). Reducing data packet size improves the load performance. In this article, I explain how to compress a Web API method and see how it improves the performance of Web API.
There are many ways by which we can compress Web API. Here I will implement it using an actionFilter that can be used on the method level, controller level and entire WebAPI.
For this, I will use a popular library for compression called DotNetZip library and this library can be easily downloaded from NuGet.
First create a simple solution and add a Web API project. Then add a class called CompressFilter.cs to the Filters folder.
Add a method called DeflateCompression.
- using System;
- using System.Collections.Generic;
-
- using System.IO;
-
- using System.IO.Compression;
-
- using System.Linq;
-
- using System.Net.Http;
-
- using System.Web;
-
- using System.Web.Http.Filters;
-
- namespace Test.API.Filters
-
- {
-
- public class DeflateCompressionAttribute: ActionFilterAttribute
-
- {
-
- public override void OnActionExecuted(HttpActionExecutedContext actContext)
-
- {
-
- var content = actContext.Response.Content;
-
- string contentencoding = ApiHeaderValue.AppContentEncoding.ToString();
-
- if (contentencoding == "GZip")
-
- {
-
- var bytes = content == null ? null : content.ReadAsByteArrayAsync().Result;
-
- var zlibbedContent = bytes == null ? new byte[0] :
-
- CompressionHelper.DeflateByte(bytes);
-
- actContext.Response.Content = new ByteArrayContent(zlibbedContent);
-
- actContext.Response.Content.Headers.Remove("Content-Type");
-
- actContext.Response.Content.Headers.Add("Content-encoding", "GZip");
-
- actContext.Response.Content.Headers.Add("Content-Type", "application/json");
-
- base.OnActionExecuted(actContext);
-
- }
-
- }
-
- }
-
- public class CompressionHelper
-
- {
-
- public static byte[] DeflateByte(byte[] str)
-
- {
-
- if (str == null)
-
- {
-
- return null;
-
- }
-
- using(var output = new MemoryStream())
-
- {
-
- using(
-
- var compressor = new Ionic.Zlib.GZipStream(
-
- output, Ionic.Zlib.CompressionMode.Compress,
-
- Ionic.Zlib.CompressionLevel.BestSpeed))
-
- {
-
- compressor.Write(str, 0, str.Length);
-
- }
-
- return output.ToArray();
-
- }
-
- }
-
- }
-
- }
In the preceding class, a value is passed using headers in a variable called contentencoding. It contains the value as GZip/Deflate/No. If No is passed, then the compression method will not be applicable and plain JSON data will be returned.
Then use the following class at the method level as in the following:
.
Execute the Web API method by commenting the DeflateCompression attribute that is applied on the Web API controller method, you will find that returned data is not compressed but simple JSON.
See the execution time when compression is not applied.
Now uncomment the DeflateCompression attribute and pass either GZip or Deflate, then the method will return compressed data and it will be 85% (approx.) less in size.
See the execution time when compression is applied.
We find that when compression is not applied then the content-length is 22583 otherwise 2783. So the difference is about 87% of data is compressed. Thus small data will travel in the network and this improves the performance of the Web API. I have used Fiddler and Postman tools for testing this application.