Recently, a RESTEasy user had a need to transfer a lot of data as efficiently as possible and found Google Protocol Buffers. He came across these blogs questioning the viability of Goggle Protocol Buffers within a RESTful architecture: Ryan’s, Vinoski’s, and Subbu’s. Although I am very late to the discussion, I thought I’d blog about my opinion on the subject to give my RESTEasy user some form of answer.

Who cares if its RESTful or not?

Firstly, who cares if it is RESTful or not?  Does PB fill a need?  If so, don’t worry about the rants of some academic or some architect that hasn’t written a line of code in years (just to be clear, neither Steve, Subbu, or Ryan fall into this academic/non-coding-architect catagory!!!).  REST is described as an architectural style, a set of guidelines, a set of attributes on what the uniqueness of the Web is.  The key words are style and guideline, NOT laws!  Whether you’re borrowing from object-oriented, aspect-oriented, or RESTful principles and guidelines, there’s always going to be tradeoffs you have to make.  It is always much more important to get a working, maintainable, on-time, on-budget system than to satisfy some academic checklist.

Treat Protocol Buffers as a Representation Format

In Steve’s blog, he rants that PB is just a starter drug that puts you on the path to RPC crack-cocaine. Steve says:

In fact, if Google had stopped there [as a definition of a message format], I think Protocol Buffers could be a superb little package.

I agree with this statement.  Treat Protocol Buffers as a representation format only.  Follow REST principles when designing your interface.  Don’t use the RPC junk available in the PB specification.

Not Self-Describing

Ryan makes a good point that PB is not self-describing.  IMO, this is a weak argument.  Unless your clients are going to be rendering agents, self-description is pretty much a pedantic exercise.  Code-based clients generally can’t make many dynamic decisions so self-description information is pretty much useless to Code-based clients.  They have to understand interactions and formats before hand, or they just can’t work.

Subbu, in the comments section of his blog, and Ryan suggest that custom media types are going to have to be defined to satisfy self-description.  Because PB is very brittle (I’ll get into this later) you’ll need to define custom (and versioned) media types to support both older and newer clients.  Something like:

application/customer+x-protobuf

and/or even embed a URL pointing to a .proto file:

application/x-protobuf;format=http:/.../customer.proto

Not Hypermedia Driven?

Ryan’s statement that Protocol Buffers is not hypermedia driven because:

Protocol Buffers do not have a means to describe links to external messages.

This is untrue.  If you’re exchanging PB representations over HTTP, there’s no reason you can’t embed a URL within a PB message body. i.e.

message BookOrder {
...
   repeated Link links = ...;
   message Link {
        required string url = 1;
        optional string type = 2;
   }
}

You have to declare these same kinds of “types” within JSON and XML as well, so I don’t see an issue here.

Stubs means its UnRESTful?

I have to disagree with this point as well.  Stubs are just a means to productively interact with the data format.  You have this issue with XML and strongly typed languages.  Is using XML schema generated JAXB classes in Java any different here?  IMO, no.

Protocol Buffers is a Very Brittle Format

IMO, perhaps the most compelling reason not to use Protocol Buffers is that it is a very very brittle format.  You need to have access to .proto file metadata to parse a PB message body.  Because PB defines a very strict message definition you’re going to have a hard time having older and newer clients co-existing as you add more information to each different message format.  XML and JSON are much more forgiving formats as generally you can ignore extra information.  I’m not sure this is the case with PB.

Edited 10/26:  I was wrong, PB is not so brittle.  Read Bjorg’s comments below.  Apologies for only scanning the PB documentation.  While the stub requirement does make it a little brittle, it does seem you can design your messages to be backward compatible.

As Ryan states in his blog, this brittleness may violate RESTful principles.  IMO though, it should always be a  measure of less RESTful vs. more RESTful, rather than the black and white approach of is RESTful vs. is not RESTful.  This is because, again, there’s always going to be tradeoffs you have to make when implementing your applications.  If you’re following RESTful constraints when applying Protocol Buffers in your implementation, it should be fairly easy to move to less-brittle types like JSON or XML if you no longer find the need to use an ultra-efficient message format like Protocol Buffers.

Conclusion

Protocol Buffers can be used RESTfully if you treat it solely as a representation format.  You can still embed URLs within message definitions to make your representations hypermedia driven.  PB is brittler format than what we’re used to and you may have versioning issues as your interfaces evolve.  Unless PB radically improves the performance of your system, you should probably stick to using formats like XML or JSON as its probably going to be easier to support them across the variety of languages that are now used within the industry.