Sound advice - blog

Tales from the homeworld

My current feeds

Wed, 2008-Oct-01

Model-View-Controller with REST

One of the big questions I think the REST software community are facing at the moment relates to what REST support we should expect from vendors, and what good REST support looks like. I have been taking a lead from web frameworks such as Ruby on Rails, and Gears.

Model-View-Controller means many things to many people. Most of those people will agree that it is a good idea, even if they aren't quite sure what it means for them in their environment.

A classical GUI application would employ application logic in a model, and its view would be a set of widgets on the screen. A controller object either intercedes when events come in from one or the other, or links the two together at display call-up time.

The prevailing wisdom in the world of server-side Web frameworks is more something along the lines of:

This works well in the common environs of web servers today. Anything that is strictly application logic that you might want to port to another framework one day appears in the model. Any routing of requests, filtering, or other request handling operations appear in the model. Views allow complex web pages to be built in a template form that the controller can populate with model data.

Success on the Server side: The Controller

I have to say that I am a fan of request routing of the form found in Rails. It is appealing to me to map a GET of{id} easily and efficiently to the getObject(id) function within the controller. It gives a reasonable degree of flexibility in relating URLs to internal controller objects, and places the list of URLs exposed by the application and their methods in an single easily-accessible and readable place. The rails implementation might include a little bit too much magic under the covers, but the central idea to my mind is clearly valuable.

Success on the Server side: The View

The views component is also useful in talking about how we move from RESTful web sites to RESTful services. The biggest change I would make here is to look at it as a two way set of transformations. It is just as important to easily process the document from a PUT request as it is to be able to produce a document in response to a GET request. Machine-to-machine communications common to services also tend to be more structured than HTML. The concept of a template per se is of diminishing use as we move headlong into structured XML payloads, so it is probably more important to include a generic data mapping tool something along the lines of an Altova Mapforce.

Success on the Server side: The Model

The model is perhaps the most interesting component of the MVC pattern. In many ways the model could be the whole of a classical SOA service. Previously you would have had (say) an EJB Session Bean as the front-end of your service. You would expose methods on this bean that operate as a thin controller object over the entities in your model.

It seems like writing a well-designed REST service involves writing an additional layer on top of the classical SOA service. You add a controller and its set of data mappings to what you might otherwise have exposed directly to the network. In doing so you gain the benefits of a uniform interface. The implementation is still Object-Oriented, even if the interface is uniform. Just like the implementation of an object's method is still rooted in the structured programming world while the interface to the object is clearly O-O. It is the vendor products that ease the development of this additional layer of abstraction that will be most useful for REST service development.

Success on the Client Side

The client-side interfaces that provide the most leverage will be the ones that cleanly separate data mapping from communication patterns, and most cleanly expose the patterns themselves to users. Built into these patterns will be any retry mechanisms, redirection, content negotiation, etc. The client won't have to deal with individual HTTP response codes. These will be baked in.

Consider a standard GET pattern. The client application code will simply say: I want data from that URL over there, and I'm using this data mapping to interpret the results. The data mapping will inform the pattern which document types it supports as input, and the pattern will do the rest. It will either reach a success or fail terminal state, and inform the application code client of that fact.