Protobuf-net: message versioning

Posted on December 17, 2012 · 2 mins read · tagged with: #message versioning

Welcome again. Recently I’m involved in a project where Protobuf-net library is used for the message serialization concern. The Protobuf-net library was developed by Marc Gravell of Stackoverflow. Beside standard Google Protocol Buffers concepts there is a plenty of .NET based options, like handling derivation, using standard Data Contracts, etc. This is the first post of a few, which will deal with some aspects of Protobuf-net which might be nontrivial for a beginner. Beside the posts, a project Protopedia was created to show cases of Protobuf usages. All the examples below are stored in this repository. All the posts requires a reader to get accustomed to the official Google Protocol Buffers documentation.

Versioning

The versioning of interfaces is a standard computer science problem. How to deal with sth which was released as looking in one way and after internal changes of the system it must be changed publicly. Consider following scenario of having two version s of one message located here. As you can see, there are a few changes like the change of the name, the addition and removal of some fields. Imagine that a service A runs on the old version of the message. A sevice B uses a new version. Is it possible to send this message from A to B, and then back to A and have all the data stored in the message? With no loosing anything appended by the B service? With Protobuf’s Extensible class used as a base class it’s possible. The only thing one should remember is to do not reuse ProtoMemberAttribute tags’ values of field removed in the past. New fields should always be added with new tags’ values.

How does it work?

When Protobufs deserialize a message, all the data with tags found in the message contract are deserialized into the specific fields, the rest of data is hold in a private ‘storage’ of the Extensible class. During serialization, these additional fields are added to the binary form allowing another message consumer to retrieve fields according o their version of the message.