Is Google Protocol Buffers RESTful?

11 Comments

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.

Improved HornetQ Spring Integration

6 Comments

I’ve been doing some work on HornetQ SVN trunk to improve the embeddable HornetQ experience (you’ll see these improvements in the next HornetQ release).  You can disagree with me, but I thought that embedding HornetQ was a bit verbose, especially for JMS, so first of all, I wrote two wrapper classes to make this easier.  While these classes will be in the next release along with a full docbook explanation, here’s what configuring JMS looks like now:

import org.hornetq.jms.server.embedded.EmbeddedJMS;

...
EmbeddedJMS jms = new EmbeddedJMS();
jms.start();

This class will look for hornetq-configuration.xml, hornetq-jms.xml, and hornetq-users.xml within your classpath.  It also has the option of manually creating configuration objects via pojo instantiation if you desire (or if you want to wire it with Spring for instance).

Simple Spring Integration

Another thing I did was to provide some simple Spring integration with the HornetQ JMS implementation.  I wrote a simple class that extends EmbeddedJMS that will register any configured queues, topics, and ConnectionFactorys direction within the Spring application context so that other beans can reference them.  Here’s an example of bootstrapping HornetQ JMS and referencing a queue within a Spring message listener container.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="EmbeddedJms" 
                class="org.hornetq.integration.spring.SpringJmsBootstrap" 
                init-method="start" destroy-method="stop"/>

   <bean id="listener"
             class="org.hornetq.tests.integration.spring.ExampleListener"/>

   <bean id="listenerContainer"
             class="org.springframework.jms.listener.DefaultMessageListenerContainer">
      <property name="connectionFactory" ref="ConnectionFactory"/>
      <property name="destination" ref="/queue/exampleQueue"/>
      <property name="messageListener" ref="listener"/>
   </bean>

</beans>

Again, this assumes you have configured HornetQ properly within HornetQ specific configuration files.  You can also manually declare HornetQ config objects within Spring and inject them into the EmbeddedJMS bean instance too if you don’t want to use HornetQ config files.

Right now, the code does not also register HornetQ objects within JNDI.  Do you think I should add this capability?  Anyways, I hope you’ll find this HornetQ + Spring integration useful in the next HornetQ release.

New HornetQ REST Interface

6 Comments

After being distracted a lot with RESTEasy releases over the past few months, I finally have something usable (and more importantly, documented) for the HornetQ REST Interface I’ve been working on.  The interface allows you to leverage the reliability and scalability features of HornetQ over a simple REST/HTTP interface. Messages are produced and consumed by sending and receiving simple HTTP messages containing the XML or JSON (really any media type) document you want to exchange.

Other than being buzzword compliant here are some of the reasons you might want to use the HornetQ REST Interface:

  • Usable by any programming language that has an HTTP client library.
  • Zero client footprint. We want HornetQ to be usable by any client/programming language that has an adequate HTTP client library. You shouldn’t have to download, install, and configure a special library to interact with HornetQ.
  • No envelope (i.e. SOAP) or feed (i.e. Atom) format requirements. You shouldn’t have to learn, use, or parse a specific XML document format in order to send and receive messages through HornetQ’s REST interface.
  • Lightweight interoperability. Since interactions are RESTful the HTTP uniform interface provides all the interoperability you need to communicate between different languages, platforms, and even messaging implementations that choose to implement the same RESTful interface as HornetQ (i.e. the REST-* effort.)
  • Leverage the reliability, scalability, and clustering features of HornetQ on the back end without sacrificing the simplicity of a REST interface.

HornetQ REST Features

  • Duplicate detection when producing messages
  • Pull and Push consumers
  • Acknowledgement and Auto-acknowledgement protocols
  • Create new queues and topics
  • Mix and match JMS and REST producers and consumers
  • Simple transformations

Visit the HornetQ REST Interface web page to find links for downloading and browsing docs, source code, and examples.

RESTEasy 2.0.0 Released!

1 Comment

Our first major release of 2010.  After a bunch of betas, I’m pleased to announce that RESTEasy 2.0.0.GA has been released.  A lot of work within the RESTEasy community has been done to improve on our last successful GA.  Follow the links from the RESTEasy website to download the new release.  Special thanks to Jozef Hartinger for the CDI integration, Eoghan Glynn for fixing a bunch of bugs, Stef Epardaud for the new Javascript client, and many others for their continuing support.  Some highlights:

  • CDI Support
  • Spring 3.0 Support
  • TCK 1.1 Compliance
  • Async Servlet 3.0 Support
  • A new Javascript API.  A javscript servlet scans JAX-RS deployments and generates Javascript code that can be downloaded that can be used as stubs.
  • Relicensed under ASL 2.0.  We switched to be compatible with HornetQ and Drools as we’re developing REST interfaces for these guys.
  • Tons of bugfixes and performance improvements reported by the community over the past 8 months.

Browse our release notes for the last few betas to look at all the bugs and features implemented.

The upcoming JBoss AS 6-Milestone 4 release will also have deeper integration with RESTEasy so that you can do automatic scanning, EJB injection, CDI injection, etc.  All the stuff you’d expect from a JAX-RS integrated EE 6 solution.

Want to rewrite JAXB?

4 Comments

I’ve been pretty frustrated with Sun’s JAXB and JBoss’s JBossXB implementations.  Here’s why:

* JAXB is not very extendable.  For example, I’d love to be able to define custom annotations that trigger callback APIs so that I can read/write custom properties from an XML document.  For example, ever try to do Map support?  I’ve also wanted to convert URLs to/from Link objects in resteasy with hooks into RESTEasy runtime for automatic URL writing.  I just couldn’t find a way to do it within resteasy.

* JAXB (both Sun’s and JBoss’s) is very slow to initialize.  Yeah, they parse very fast, but initialization speed is very slow because it has to do a lot of reflection on the classes that make up the JAXBContext and build a lot of data structures to do quick parsing.  You might be saying, “Big Deal!”.  But what I’ve found with JAXB and JBoss’s impl is that for the meta-models we’re trying to parse in JBoss AS, it can take as much as 1 second to initialize all the models.  That’s 1 second more added to boot time.  1 second to make embedded/unit testing slower.

So, this is why I started the fast-jaxb project under the RESTEasy SVN.  The way it works is that you provide it a set of classes and it generates Java code that uses SAX to parse XML.  The problem is, I haven’t had the time finish it, which is why I’m blogging to ask if anybody is interested in taking it over (or suggesting a good alternative for solving the goals/problems mentioned above).  Fast-JAXB has basically no initialization overhead compared to Sun’s JAXB implimentation.  I haven’t worked on the extension points though, nor do I support all the JAXB annotations.  I have also only worked on parsing XML, not generating XML.  Anybody interested in taking it over and driving it?  Give me a ping here on this blog…

I like my iPad

3 Comments

Got an iPad delivered last Friday.  I didn’t get the 3g one.  I haven’t been too happy with AT&T’s data network.  I like the iPad.  Its great for browsing the web at breakfast.  What I bought it for really was for reading books.  I read like 5+ trashy sci-fi/fantasy books a month and my home office is starting to be overflowed with paperbacks.  The iPad seemed like a better solution over the kindle as, a) it wasn’t much more b) I probably will find other uses for it.  I must say, reading from the iPad is 10 times better than reading from a book.  Its easier to hold.  I can make the font bigger.  Built-in nightlight.  Automatically remembers where I was in book.  I think I would pay to subscribe to magazines and local newspapers that had an interface designed for the iPad, especially if the content could be delivered electronically so you could view it offline.

Apache damaging to Open Source

10 Comments

I just read an interesting blog by Savio questioning the value of LGPL.  IMO, he has something right, the OSS license chosen for a project is not that important as far as adoption or business goes.  The most important driver for OSS is and always has been the brand of the project.  Like their commercial counterparts, how the project is perceived by consumers is what drives both adoption and business.  So, I agree, LGPL doesn’t add a lot of value.  But, it goes both ways, the Apache license is also not that important either.

If you boil it down, the distinctions betwen GPL, LGPL, and ASL are pretty much meanlingless to most consumers of OSS.  How so?

1. The viral nature of GNU bases licenses is only triggered when binaries are distributed.  Most consumers of open source do not distribute software publicly.

2. LGPL is also not an issue for ISVs as long as they leave the binary as-is.  Its viral nature is triggered when the project is both modified and distributed.

So, when you take these two points together, the number of people affected by the differences between GPL, LGPL, and ASL become fewer and fewer.  GPL does not affect > 90% of OSS consumers.  For LGPL, the number of people actually affected by the license becomes a number that you can probably count on one hand.  The ones affected are the ones who actually want to use derivatives of the project within their own competing initiatives that are not LGPL-based.   So, do you see how meaningless it truly is?

Why making these distinctions is damanging

This all brings me to my final point.  The whole push by Apache.org and its minions that ASL is the one true license is just damaging to open source.  When you consider the handful of individuals affected, you got to question the motivation for it, especially when you match it up to LGPL.  The thing is though, highlighting the differences only helps those handful of people that have selfish motives and/or want to exploit OSS for commercial gain.  Believe me I’ve lived this.

Back in 2003, a group of JBoss contributors tried to fork both the JBoss code base and the JBoss business.  IMO, their motives were mostly financial.  They wanted a bigger piece of the pie that Marc Fleury was unwilling to give up.  Whether or not they were right to do this is besides the point, there are good arguments on both sides, and whats done is done.  They initially derived themselves from the JBoss codebase, went to Apache, and thus Geronimo was born.  We complained that their derivation was both a copyright and LGPL violation.  In the end, they started over from scratch (don’t think the LGPL had value for JBossians back then?  think again!).  When Geronimo 1.0 came out, their feature set was vastly inferior to JBoss so their push was that it was the only Java EE implementation that was ASL.  That LGPL was scary and the only way to get over the fear was to use ASL-based projects.  IBM got into the act when they purchased Gluecode (and all the Geronimo developers) and embraced Geronimo as their children’s edition of Websphere.  Again, the main push was that Geronimo was ASL based.

We then come full circle to 2010 with history repeating itself (well, sort of).  You have Tom Bayerns leaving Red hat for Alfresco to create a competing BPM engine.  Now, I consider Tom a friend, and I completely understand his reasons for leaving Red Hat.  That being said, launching a new open source BPM engine with the premise being “we want to create something in ASL because it is better for our business”, is not the way to go about it.  Again, it smacks all over of having nothing but the zero-add of the ASL distinction.  And, is just completely irresponsible.

If you are an Apache guy, you should be appalled by behavior like this when it happens.  Individuals and companies that use ASL as a weapon to further their own selfish and commercial needs should be castigated and called out instead of championed as the reason why ASL is so cool and LGPL is so bad.  Respect the choice of other open source developers, propagating the myth that an ASL project is superior to a LGPL project because of license distinctions does nothing but hurt the open source movement as a whole.  We need to stop eating our own.

Finally, I just don’t want to bash on Apache and ASL.  Joining the GPL revolution isn’t so hot either.  The fear of GPL virality is used extensively in the dual-licensing ploy of commercial interests.  Think MySQL.  For me, I would never pick GPL, because I believe in the freedom of letting ISVs distribute my stuff as-is.  As for LGPL vs. ASL?  I could care less, it really doesn’t matter.  You don’t see JBoss caring so much either.  Drools is still ASL as well as a number of other jboss.org projects.

Anyways, have fun with this, and remember taking any one position to seriously is unhealthy.

New Macbook Pro+SSD+I7 Performance

4 Comments

I just bought a new Macbook for myself.  Its a 17″, I7 (2.66ghz), 8 gig ram, 256Gb SSD (solid state drive).  The performance of the new system is what I had hoped.  To compare, I decided to boot up JBoss AS 6 trunk and compare it against my old Macbook (2.6 Core 2 Duo, 4gig ram, 7200rpm HD).  Since OSX does do disk caching, its good to record both the initial JBoss AS boot time vs. subsequent boot times.

Old Macbook:

Time #1: 39.3 seconds

Time #2: 26.2 seconds

New Macbook:

Time #1: 20.8 seconds

Time #2: 19.1 seconds

Observations:

Initial boot is almost 47% faster for new machine, while, after disk cache comes into play, it is about 27% faster.  Now from what I’ve read, the I7 starts at 2.66ghz and starts to clock up to 3.3 ghz as you need the processing power. 3.3ghz is 27% faster than the 2.6ghz, so it make sense that Time #2 comparisons have a 27% difference.  What’s interesting to note is Time #1 comparisons as (maybe I’m wrong here) it looks like the SSD plays a huge performance role for initial reads, which is what I had hoped.  I could not get any specs for the 256Gb SSD drive from Apple’s web site or from calling up their sales force on the phone.  Since the new Macbooks are only a few weeks old, I could only get information by looking at SSD comparisons from various blogs, articles, and forum posts of older Macs.

Building Resteasy

I also compared building Resteasy with the old vs. new machine.

Old machine: 193 seconds

New Machine: 144 seconds

What’s interesting about these numbers is that the new machine is only 25.4% faster.  This looks like to me that SSD writes are slower than the 7200rpm box.  Yeah, I’m too lazy to download a diskbench, but you get the idea.  I did find this though (scroll to bottom to look at disk comparisons).  This gives some hints I think.

Google’s ‘worries’ are just a ruse

13 Comments

I think this Google announcement that they are worried about Java being rudderless is just a ruse.  I guarantee they are planning to take what they’ve done within Android and position it as a new language to replace Java.  This “the sky is falling” statement by Josh is just setting the stage for it.  They’ve pretty much done it with every non-standard library (do their own thing), so, IMO, setting the stage for a new language is right up their ally.  Plus,  creating your own language is the ultimate expression of ego and we know there’s lots of it at Google.  So, when Google announces their replacement for Java, remember, I told you so…

REST core values

2 Comments

REST attempts to answers the questions of: What properties of the web have made it so successful?  How can I apply these properties to my applications?  While REST is simple, it takes awhile to figure out how to follow this architectural style effectively when designing distributed interfaces.  REST promises greater decoupling, change resistance, and scalability if its principles are followed.  The thing is though, for anybody not fresh out of school, we’ve heard these types of promises again and again over the years made by various industry efforts: DCE, CORBA, WS-*, and insert-your-favorite-distributed-framework.   While the success of the Web leads me to believe that REST principles are strong, there has to be something more fundamental that it promotes or we’re never going to break the cycle of complex, bloated, infrastructure runtimes.  That’s why I’ve adopted a set of core values for myself when writing RESTful interfaces.

Simplicity

Perhaps the most important reason why developers initially are attracted to REST is that, at its core, REST is very simple HTTP interactions.  A good restful service can be understood simply by looking at the messages that are exchanged.  If you were around in the early days of the web, did you look at HTML source to learn how a specific website wrote their page?  Same applies to RESTful web services.

Zero Footprint

To write a RESTful web service all you need is a platform that can web requests.  You can write restful services using Apache+CGI+(python/php), Servlets, JAX-RS, Restlet, Rails, Grails, whatever.  From a client perspective, all you need is an HTTP client library.  While frameworks can make you more productive, just using an HTTP client library is practically productive enough.

Lightweight, true, interoperability

Have you ever had trouble getting two different CORBA or SOAP vendors to interoperate?  What about getting two different versions of the same vendor’s CORBA or WS-* stack to interoperate?  These are common problems that happen every day with traditional stacks.  Because REST focuses on exchanging representations through ubiquitous protocols like HTTP, these interoperability problems, on the protocol level, pretty much don’t exist.  HTTP is everywhere and well supported.  HTTP content negotiation allows clients and servers to decide, at runtime, what formats they want to exchange.  REST+HTTP removes the vendor interoperability problem and allows developers to focus on application integration.

Frameworks for productivity, not for coupling

REST frameworks should help with developer productivity and not create a lockin between the client and server that requires the framework’s runtime be installed on both sides of the pipe.  I feel this will lead to interoperability problems and complexity.

I’ve been yelled at before for stating my core values on why REST is important to me.  I think I was misunderstood.  I think there’s a distinction between what you want to accomplish and how you accomplish it.  Right now REST is the how, and my core values are the what.  Also, these core values are why I’ve been skeptical openly about things like WADL, Atom, RDF, and PATCH and why I’m nervous about how transactions are going to turn out in our REST-* effort.  After all these years, its so important to get things right.

Older Entries Newer Entries