ASP.Net Web API is a lightweight framework used for building stateless and RESTful HTTP services. Protocol Buffers from Google is an extremely fast, language independent, platform-neutral, extensible and easy-to-use binary serialization format that enables you to serialize structured data.
In using Protocol Buffers as the serialization format when passing data over the wire, you can get huge performance benefits primarily because the Protocol Buffers serializer is very fast and consumes much less bandwidth thanks to its ability to generate smaller packets of data. This results in reduced network bandwidth consumption and hence faster responses.
Getting started
The first step is creating a blank ASP.NET project in Visual Studio 2015 and check the Web API checkbox when selecting the project template. You should then install the "WebApiContrib.Formatting.ProtoBuf" package using the NuGet package manager to use Protobuf in your Web API project. Next, you would need to register the formatter by specifying it in the Web API configuration as shown in the code listing below.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Insert(0, new ProtoBufFormatter());
}
}
As you can see, we have inserted the protocol buffer formatter using the Insert() method and specified zero as the index in the first parameter when calling the Insert() method. This is necessary to ensure that the formatter you attach to the Formatters collection of the HttpConfiguration object becomes the default formatter.
Next, you should decorate the types you would like to be serialized in protobuf format using the ProtoContract attribute.
[ProtoContract]
public class Contact
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string FirstName { get; set; }
[ProtoMember(3)]
public string LastName { get; set; }
[ProtoMember(4)]
public string Address { get; set; }
}
Here is how our Web API controller would look like.
public class DefaultController : ApiController
{
public List<Contact> Get()
{
List<Contact> lstData = new List<Contact>();
Contact contact = new Contact();
contact.Id = 1;
contact.FirstName = "Joydip";
contact.LastName = "Kanjilal";
contact.Address = "Opp Country Club, Begumpet, Hyderabad, Telengana. “;
contact.Address += “ PinCode - 500 016. INDIA.";
lstData.Add(contact);
return lstData;
}
}
To consume the Web API you have just created, you can create a console application and then import the "WebApiContrib.Formatting.ProtoBuf" package to your project via NuGet. The following code listing shows how you can invoke the Web API we just created from a console application.
var client = new HttpClient { BaseAddress = new Uri("http://localhost/Protobuf/") };
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
HttpResponseMessage response = client.GetAsync("api/Default").Result;
if (response.IsSuccessStatusCode)
{
List<Contact> p = response.Content.ReadAsAsync<List<Contact>>(new[] { new ProtoBufFormatter() }).Result;
Console.WriteLine("{0}\t{1}\t{2}", p[0].FirstName, p[0].LastName, p[0].Address);
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
Note that you should add "application/x-protobuf" in the Accept Header at the client side. You should also add the "ProtobufFormatter media formatter in the response object so that the proto object that is being returned in the response can be deserialized. You can use Fiddler as well to test your Web API.
I did test the performance of Protobuf by creating two Web API controllers -- one that uses Protobuf and another that doesn't. Both of these controllers used the same entity class (I used the same Contact class discussed earlier in this article) to populate and return the data to the user interface. And, I could observe huge performance gains. Just give it a try yourself.
You also have a few JavaScript libraries that can deserialize the protobuf objects that are returned to the user interface. I've used the ProtoBuf.js library -- it's simple and easy to setup and use. So, you are no way constrained to using protocol buffers in either the service layer or the presentation layer of your application. Most importantly, using protocol buffers is easy -- you can get stated using it in your applications.
Protocol Buffers being a binary serialization format, the messages generated aren't human readable. On a different note, Protocol Buffers still provides limited language support. Also, Protocol Buffers is not a good choice when you need to transmit a lot of data over the wire and consume it in your web browser. In essence, albeit its many advantages, there are a few downsides to using Protocol Buffers as well -- there isn't any technology that doesn't have downsides, correct? I would always prefer using Protobuf as the serialization format if there isn't any need to transmit a huge amount of data over the wire.