Search code examples
asp.net-coreasp.net-core-webapimsgpacklz4

How to enable LZ4 compression for messagepack content type in Asp.net Core Web API


I'm trying to enable MessagePack content type on a .net Core Web API Project that I'm working on.

After some research, Installed this nuget package and added below code in the startup file. Easy enough ! Now I can see msgpack content served through my APIs.

services.AddMvc().AddMessagePackFormatters(c => 
{
  c.FormatterResolver = ContractlessStandardResolver.Instance;
  c.SupportedContentTypes.Add("application/x-msgpack");
  c.SupportedExtensions.Add("mp");
});

Now I would like to apply LZ4 compression on top of it to reduce the payload size as mentioned in here. And I couldn't find any nuget packages to add this functionality or figure out a way to plugin LZ4 compression. In few blogs, I've read that LZ4 compression is inbuilt in MessagePack. I couldn't understand what that means and there's very little documentation out there about this stuff.

I'm new at this compression/de-compression stuff, so any help is appreciated.

Thanks


Solution

  • You have to write a custom media type formatter because the compression is used in a different module. Instead of MessagePackSerializer you have to use LZ4MessagePackSerializer. The usage is the same. Also the recommended MIME type is application/msgpack.

    See this basic example:

        public class MsgPackMediaTypeFormatter: BufferedMediaTypeFormatter
        {
            public MsgPackMediaTypeFormatter()
            {
                SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/msgpack"));
            }
    
            public override bool CanReadType(Type type)
            {
                return !type.IsAbstract && !type.IsInterface && type.IsPublic;
            }
    
            public override bool CanWriteType(Type type)
            {
                return !type.IsAbstract && !type.IsInterface && type.IsPublic;
            }
    
            public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
            {
                return LZ4MessagePackSerializer.NonGeneric.Deserialize(type, readStream);
            }
    
            public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
            {
                LZ4MessagePackSerializer.NonGeneric.Serialize(type, writeStream, value, MessagePack.Resolvers.ContractlessStandardResolver.Instance);
            }
        }