ASP.NET Core Protocol Buffer Formatters

Intro

I created a library for ASP.NET Core which lets you use Protocol Buffers in your controller’s requests / responses. The library is available on my GitHub and is licensed under the MIT license. See the repo on installation instructions.

Background

ASP.NET Core is one of my favorite web / backend frameworks for a variety of reasons. One them being how flexible and customizable it is. From my experience just about every part of it can be replaced in some way.

That brings us to the topic of this blog post: ASP’s Content Formatters. Content Formatters convert the request data into the DTO / model for your controller endpoint and then convert your DTO / model back into the response data from your controller.

Typically when transferring data the content type of the request is ‘application/json’. In this case ASP has built in formatter which converts the JSON data into your endpoint’s DTO / model C# object. In other words, you’ve probably used ASP’s content formatters before without ever realizing it. While this is great, it’s even better that developers can writing their own formatters to handle alternate content types.

One alternate to JSON are Protocol Buffers (from here on out known as protobufs). Protobufs were developed by Google so I’ll let them explain them:

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

This post isn’t intended to be an in-depth look into protobufs so if you’d like more information on them, please checkout Google’s site. The important parts to know are they’re better than JSON since protobufs are strongly typed (like C#), aren’t string based (which means they take up less bytes on the network and have better performance when de/serializing), and don’t use reflections (many C# JSON libraries don’t work correctly in Ahead of Time environments because they rely on reflections).

For these reasons (and more) protobufs can be an ideal way to serialize / deserialize data.

Protocol Buffer Formatters

So how can you start using protobufs in your own ASP.NET Core projects? With my library!

Start by adding the nuget package to your project:

Install-Package AspCoreProtobufFormatters -Version 1.0.0

Next, you’ll need to edit your Startup.cs file to call the AddProtobufFormatters extension method on a MvcOptions object. If your just using controllers it’ll look like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options => 
    {
        options.AddProtobufFormatters();

        // configure other options
    });

    // configure other services
}

Or, if you’re using full MVC it’ll look like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => 
    {
        options.AddProtobufFormatters();

        // configure other options
    });

    // configure other services
}

And that’s pretty much it for the server code! From there all you need to do is use protobufs as request argument or as the response in your controller’s action methods.

The client will need to set the content type of the request to ‘application/x-protobuf’ in order for data to be serialized / deserialized in protobuf binary format. If the client sends ‘application/json’ ASP.NET Core will continue to use its builtin JSON formatters (even if the DTO / model is a protobuf).

If you ever need to convert the protobuf into a human readable option the client can set the content type to ‘application/x-protobuf-json’. This will convert the protobuf to / from JSON using the JSON conversion methods built into the protobuf library. Note: Google recommends only using this for debugging purposes as the JSON conversion is ‘generally not optimized’. Warning: ‘application/json’ and ‘application/x-protobuf-json’ use different JSON converters and therefore aren’t guaranteed to produce the same results nor be used interchangeably. If you actually want JSON, use ‘application/json’; if you want to debug the serialized protobuf in a human readable way, use ‘application/x-protobuf-json’.

And that’s it, for real this time! If you like this library feel free to star it on GitHub or reach out to me on twitter @jamcar23.