As a follow-up to my previous article about WebAPI, I received an interesting question from a friend on LinkedIn: Is there a way to emit data in Protobuf format?
This one got me thinking... ProtoBuf is short for Protocol Buffers which is a data format technology invented by Google to allow for maximum compression of structured data that can be interpreted by any programming language. Google says: "think XML, but smaller, simpler, and FASTER", and I think they may be right. According to Google's own benchmarks, Protocol Buffer format is 3-10x smaller and 20-100x faster on the wire.
Fortunately, there is a pair of NuGet packages available to help our WebAPI application handle the protocol buffer format. From within my WebAPI application, I can use the NuGet console to install these two packages with the following command:
Install-Package WebApiContrib.Formatting.ProtoBuf
Once this command completes, the protocol buffers library protobuf-net
should be installed as well as the appropriate media formatter in the WebApiContrib.Formatting.ProtoBuf
library. The next step to configure WebAPI is to configure the application to be aware of the new formatter. This is accomplished with the following command in Application_Start
in the global.asax.cs file:
protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configuration.Formatters.Add(
new WebApiContrib.Formatting.ProtoBufFormatter());
RegisterRoutes(RouteTable.Routes);
}
Finally, we need to configure the data we are going to transport so that the Protocol Buffers library knows how to serialize it. This is accomplished with a series of attributes on our Team
class:
[ProtoContract]
public class Team
{
[ProtoMember(1)]
public string City { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}
The ProtoContract
attribute tells the serializer that this class can be formatted with protocol buffers. The two ProtoMember
attributes assign a location to the properties in the resultant stream of data. The numeric locations identifiers should be continuous and start with one.
With this minor bit of configuration, we can start our application and open Fiddler to easily test our new protocol buffer aware API. If I point Fiddler to the standard location http://localhost:4829/api.my, I'll get normal JSON output:
[
{"City":"Philadelphia","Name":"Phillies"},
{"City":"Boston","Name":"Red Sox"},
{"City":"Cleveland","Name":"Browns"},
{"City":"Houston","Name":"Astros"},
{"City":"San Diego","Name":"Chargers"}
]
but if I go into the Composer tab of Fiddler and submit the request with an accept header of application/x-protobuf
:
Fiddler Composer - Sending a GET request for Protocol Buffer content
The results returned are the protocol buffer format, not entirely visible to us as text:
Protocol Buffer Formatted ResultSet
We didn't change any of our business logic. We didn't change any of our data access code. By simply adding an additional media formatter, WebAPI was able to handle and format the resultset
as requested. What else could you format with WebAPI? What other request formats could you interact with? Let me know what you think in the comments below.