The prevalent programming model today is OO. Whatever you do, you'll end up writing some classes in some form of (light or heavy) container which offers a series of APIs (OO based of course) to simplify application development. If you are lucky, you'll be able to sprinkle your code with some annotations that often add (non-OO) semantics to a given OO container. In many respect, our industry is bit like the civilizations of the Americas (Incas, Mayas, Aztecs...) who achieved great things, yet they never discovered the wheel wasting tremendous amounts of productivity in the process.
So I was not surprised to hear Stefan Tilkov admitting OO is pretty much a barrier to RESTfulness. He explains in latest interview on InfoQ in response to that question: " we have frameworks today in Java, Ruby and C# that try to map to the REST model, but often it seems like very much a one to one mapping with methods which ignores in some way like, what about hyperlinks or hypermedia. Do you think that frameworks are constraining REST?"
I would possibly not say they constrain it because essentially you can build a very RESTful application using Perl and CGI. There's nothing that stops you from doing that; it's just pretty much work... Essentially you write a class and you can do a 20-line class and it would work very nicely and expose that [a resource representation]. It is pretty weak in its support for hypermedia, you're right; even on the server side it is pretty weak because there is no - I don't think anybody really had such a great idea yet. So there are some ideas popping up. That's from the server side of things, which I think is the easy part. I think the really hard part is the client side. I don't really have a great answer on what a client API should look like, because it is pretty hard to find a good mapping of these concepts to some sort of programming model that would be equally valid for any kind of RESTful service.
Yes, you heard him right, he is trying to find a good mapping between HATEOS and OO. LoL... Talking a square peg in a round hOOle ... This is actually not surprising coming from a someone who thinks that SOA and WS-* are broken because a "code-first" approach does not work and generates bloated XML Schemas.
So, how do we go about solving that Fermatian problem? Would a GPL work? not quite, the semantics of "links" are totally foreign to any GPL I know, not to mention feeds or resource representations. A DSL? of course... actually, no quite either, you need a real programming model, you are going to write some serious business logic on the client side. MOP? yeahp, a RESTful client needs a new programming model, a RESTful Solution Model. The problem with GPL is that they are not declarative enough (even with annotations), the problem with DSL is that they are not imperative enough. That's why you need MOP. There is also the illusion of the magical programming language that can make it easy to solve every problem known to man and beyond. The reality is that there is no magic bullet. You have to create your solution model, or at least use one suited to your problem. A given solution model will never fit all problems. So, what would a MOP Solution Model look like? Here is a proposal for the client of a Purchase Order RESTful Web Service.
The client enters a bookmark (which is injected via an assembly mechanism). You reach a given state of the UI based on a response media type (Note, some Content Types are missing in this sample code). The bookmark is supposed to respond with a poServiceEntry response media type. The media type contains at least 3 links: getPOs, createPO and getCopyrightNotice. These links are declared static for the client, meaning that they are available in any state of the client, unbeknownst to the PO Service. The links share a common identifier between the response and the client code. Unless, we do a true semantic mapping, and aside from digital telepathy, there are few options here.
When the user of the client invokes a link, the PO Service Response will decide the next state of the client (if you don't like the word state, you can use view instead). For instance, upon requesting all the POs of the service, the getPosResponse state will be reached. The client expects to be able to bind the PO feed as well as the selectPO action. This action is repeating for every element of the feed, this is why it has a *.
Upon the selection of a purchase order, the client enters the getPoResponse state. Here we are expecting a form coming back in the response. The form binding is read-only at first. We also insert a local action, that sets the form edit mode ('@'). This could also be done with a service call and a new editable state if we wanted to lock the record on the service side. When the form is set in edit mode, we add to more actions: update, delete and cancel. You can also add some validation, transformation... to a particular action. Here we want to apply some client specific validation (regardless of the validation rules of the service).
Of course, the programming model would not be much useful without an exception mechanism, that's why I included one based on HTTP error codes.
In the end, I know people will claim that they can create an API which implements "links" or "resource representations" (this is actually not that easy). But this is precisely the point of MOP. Delivery teams create and recreate conceptual solution models that they translate into (en)coding patterns and practices. As team members leave and join the project, as deadlines and bug fixes pile up, the conceptual models fade and the code becomes brittle hard to maintain and understand. The coup de grace happens when the technology in which the conceptual model was implemented retires, at that point it is hard to find anyone who would like to work on this code base and only emergency maintenance is executed since very rarely a system will have enough resources for a complete rewrite. MOP is just about making the solution model explicit, about avoiding this pointless and costly mapping to your favorite execution environment be it OO-based, functional or process based. MOP is about making the solution model explicit and separate from technology AND architecture.
That's all for today.
RESTful Client Programming Model by Jean-Jacques Dubray is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Based on a work at www.ebpml.org.
thank you for your comment. Actually, I was not trying to create “the” client programming model, but I wanted to illustrate how easy it was to create a model if only you would leave OO behind.
In the process of trying out, I found out, as you point out, that there is some value to keep the state of the client and the resource separate.
The other advantage I see of the proposed model is that it makes no assumption on the sequence of events since the binding happens on Resource Representation types, if an HTTP request returns a particular type it binds to that one.
I also wanted to show that there is simply no real short cut to a contract between the client and the resource.
>> The hypermedia engine becomes a mediator
>> between the platform and the services and thus
>> decouples the two
I am not sure I fully understand that, for me the coupling is innevitable, unless a user is capable of interpreting the client, if you want any kind of software agent to deal with the links of a resource representation, I don’t see how the decoupling can happen. It is not a CORBA coupling, but it is still a coupling, a shared understanding of the actions, inter-actions and trans-actions.