Service Oriented User Interfaces-How soon is now?

My last post got picked up by slashdot and it generated a fair amount of discussion. This one was already well on the way and I didn't want to rewrite it completely, but I did want to address the criticism against mindless adoption of the latest set of acronyms, of innovating for the sake of innovation.

In my consultancy, all experimentation with development practices is driven solely by the need to provide my clients with more and more value. I do this by increasing software quality and decreasing time to market. On a practical level I simplify and regularize the way my team works (this includes not writing code whenever possible). If I'm sharing these practices it's because they are helping me achieve these goals, and I think others may be interested.

There was another criticism having to do with pointless layers of abstraction, especially in java development. I've seen a lot of pointless abstraction (and indirection) in my time. I hope I successfully answer that charge in-line.

A company operates their primary line of business application in a highly automated environment. One where it is as likely that the client for for the middle tier is a python or perl script as a browser based application. In the past they had made the mistake of creating a separate facade for each sort of client. PHP for the web application, perl and python libraries each hitting the database and reproducing any required business logic.

It's not hard to imagine the problems this led to. So the first thing I promised was that when we rewrote the app there would be a single interface no matter the client (including the UI). In 2009, it seemed reasonable to pursue a RESTful apporoach and indeed an extreme form of it since we decided that all interaction with the middle tier would be via http and JSON.

This approach had a number of results and consequences that I think are worth sharing in 2010.

By treating all clients equally, certain aspects of controller on the server dwindle, the part that knows knows anything about a particular presentation technology like Struts, Wicket or an asp page. The middle tier is a RESTFUL wrapper around EVERY application feature.

For .net applications we can use the WCF REST Starter Kit. For java applications there are a dozen excellent implementations of the JAX-RS (jsr311) specification. The point is that the service layer of my application stay essentially the same, no matter how we build the presentation layer.

As a manager and a developer, I think this is great. I'm always trying to make all my applications look the same no matter the technology stack. Using a common set of idioms makes it easier to support existing applications and to build new ones.

Rather than adding yet another layer of abstraction we make clear of a boundary between system components (what made this boundary ambiguous were the different types of "shim" code dealing with different presentation layer technologies).

What about the additional work needed to translate our domain objects to JSON, XML or some other client side format? JAX-RS transparently marshalls and unmarshalls several flavors of JSON and XML for my service layer. I write my service methods as I normally do, working with my domain objects. Clients can even negotiate the type of content returned by specifying an html encoding. True, marshalled domain classes have to be identified with the @XmlRootElement annotation and the REST URis are specified on the service interface (The WCF starter kit works in a similar fashion):

<pre>@Path("test")  
@Produces("application/json"  
@Produces("application/xml")  
@Consumes("application/json")  
public interface TestService {  

@PUT  
@Path("testput/{val}")  
public void testPut(@PathParam("val")String val);  

@GET  
@Path("test-error/")  
public void testError();  
}</pre>

The service layer and the ways it is accessed is completely specified in one place and this seems like a very good thing to me. Java clients in the same JVM can call the service code directly. As an added bonus remote Java clients can also use a proxy system (you must have the source of the domain objects and the service layer interfaces) that allows for idiomatic and IDE assisted access to the services:

@Test  
 public void testStartPocessNoPipeline() throws Exception {  

 RegisterBuiltin.register(ResteasyProviderFactory.getInstance());  
 DeployService client =  ProxyFactory.create(DeployService.class, "http://localhost:8080/ext-webapp/rs");  
 SkylineProcessWrapper pipelineresults1 = client.startAssetPipeline(UUID.randomUUID().toString(), "NONE",  
    "boss_animation", "something nice",new ArrayList());  

assertNotNull(pipelineresults1);  

 }

It's even better if I use grails. The jaxrs plugin automagically generates a RESTFUL service layer for all CRUD and listing, filtering, sorting behaviors for my domain objects, eliminating huge swaths of normally hand-coded boiler-plate service layer! The anti-scaffolding folks may be right when they complain that the CRUD screens produced by (G)rails aren't suitable for production apps, but I think the service layer generated in this fashion will be.

I think it becomes harder to write a good service layer though, since we really don't know exactly how the conversation with clients will go (this makes sense in the age of SOA and the mashup). We have to embrace an open-endedness which is difficult to do and that goes against many of our instincts as developers. And somtimes I wonder whether the RESTFUL grammar wll be rich enough to support all possible application semantics.

Test driven development (TDD) helped us. Our tests are the service layers first and best clients. We also prototyped a browser based interface using Ext JS. Our application is a work flow and job tracking system, and I think we managed to put together a middle tier that will support significant variation of functionality without needing to change very much. It helps that it's a wrapper around a mature and full-featured work flow library, JBoss jBPM. Wherever possible we pushed application variablity down into the work flow system.

I suspect that in coming years, the level of flexibility achieved in the service layer will be one of the key ways we distinguish developer excellence.

As the controller orchestrating the conversation with the user moves into the browser, client side coders will have to rise to the occasion by taking on the controller portion of MVC. They will always pass an XML or more likely a JSON model back and forth to the server via a RESTful interface. They may manipulate the DOM directly using javascript or use a rich client framework. I think their work will become more valuable, including monetarily, as they take on the job of fundamentally driving user interaction. Certainly they will be less frustrated and more productive as a single way of doing things they control takes the place of dozens of server side templating systems. But they will have to learn new tools and techniques for orchestrating the conversation with users.

I've been very impressed with Ext JS, a client side RIA framework. It provides an excellent suite of UI components, but is even better at providing tools for putting the controller part of the application in the browser though its Ext.data.store construct and its ability to save state on the client. Plus, it's another one of those rare tools that just make sense, where you can try things and they just work.

I don't imagine swapping out presentation layers the same way as we sometimes swap databases for our Hibernate or JPA entities. In every case client code is going to have to know something about the business at hand. The users at the company I introduced in the beginning of this post are incredibly sophisticated. If a group of them doesn't like the way part of our web based interface works, they'll write their own. Our flagship human interface is written in flex and they are unlikely to replace it, but we've given them the tools to do so but in a safe and controlled manner. The innovations they come up will improve the application for everyone.

Certainly this "let a thousand flowers bloom" philsophy may not always be appropriate. But as we work this way, there'll be fewer and fewer times when a small change request for the way a client works will require rework all the way down into into bowels of an application. That's no small thing, especially in tightly controlled environments. This should include changes to the relational database, but that's the subject for another post dealing with the goodness of nosql databases.