How did we end up here?
Fifteen years ago, at the end of the two-tier client server age, people started to realize the importance of distinguishing between at least three different layers in the architecture. A business layer, providing a convenient API allowing you to address a particular business concern, a data layer storing related data, and a presentation layer providing a convenient user dialog on top of the business logic.
At some point, it became apparent that modularizing like this was not going to cut it. We needed to modularize the business tier and create ‘services’ addressing particular concerns. This is what we ended up having:
In our new world, we did have services with clear interfaces, and these services communicated through each other through clearly defined interfaces (either local or remote). However, we were cheating. In most cases we couldn’t figure out how to preserve consistency without relying on the convenience provided by SQL solutions, so we allowed for some ‘integration’ at the data layer; that is, we stored all data in a single database, and essentially faked isolated services on top of that. And then – since we still needed to be able to present a single integrated user interface – we created a single presentation layer component that pulled in everything it needed from the business logic below.
The rise of SOA essentially caused us to focus on service boundaries even more. And although we had different schools of thought – and there were actually quite a few folks who felt like service oriented had nothing to do with web services – the focus started to shift from a modularization problem to a remote integration problem. So it was essentially about pulling the different things already identified even further apart.
Now, if you pull services apart like illustrated above, the link to a single data store is obviously going to hurt. So a good thing about everything that happened back then is that everybody started to feel the pain of linking to a shared data store. The technical complications forced people into making services have their own data layer, and drop ‘integration’ on a data tier. It might not have been the ideal reason for doing it, but the net effect was this:
This is when people also started to realize that ACID wasn’t going to cut it in the long run, and we should consider other was to preserve consistency, paving the way for NoSQL and spreading the word on compensating transactions and idempotence.
So what do we have now? On the plus side, we do have services that are pretty much isolated from each other (good!). However, the integration with the UI is still pretty much one big blob. And for some reason, that is considered quite ok. But is it really? In many cases, the dependencies between the presentation layer and the business logic layer are pretty tight.
Let’s take a payment service as an example. Whatever the payment service will require from the user to enter, obviously needs to be entered in the presentation layer. Replacing one payment service with another type of payment service will most likely have big implications on the presentation layer. At the same time, the rest of the dialog offered to the user probably is completely independent of the dialog presented when dealing with the payment service.
So, if we feel strongly that services should be isolated from each other as much as possible (free interpretation of Parnas) and keep what needs to be exposed to an absolute minimum, why not cut the presentation layer apart as well?
Presentation layer service integration
For some reason, the idea of presentation layer based integration doesn’t land very well in a world once dominated by the WS-flavor of SOA. However, mashups are omnipresent on the Internet. It’s just often not considered as a way to do integration of services within a single system in a single organization.
Organizing your service oriented architecture as outlined above bares some resemblance to the ideas expressed by Allen Holub more than a decade ago, but then applied on a larger scale. The central message in his article was to prevent objects from exposing too much of their own internal state by making objects responsible for providing a UI representation of themselves. That sounds like a horrible idea according to the model that promotes strict separation between presentation layer and business logic layer, but I think it makes perfect sense in a service oriented architecture.
Back to the payment service example: let’s assume for a minute that the left-hand service is a shopping service (including the presentation layer dialog with the user) and that the right-hand service is the payment service. Integrating the services would require some integration on the presentation layer as well as the business logic layer.
When the user selects a payment method associated to a particular payment service, the payment service’s presentation layer should be pulled up, passing clues on what to do after the payment succeeded or failed. From that point on, the payment service itself is in control of (part of) the dialog.
When the payment is cleared, the payment presentation layer will hand back control to the shopping service’s presentation layer. However, the business logic layer might communicate more information on the status of a payment through the SPI defined by the shopping service. (Like settlement related information.)
By considering the presentation layer to be part of the actual service, you introduce a couple of new degrees of freedom. First of all, depending on how the integration in the presentation tier is done, you might have the option to have part of the user dialog executing in the same address space as the business logic. Instead of having to do several remote calls for pulling together all data to be presented to the user, the presentation layer would do all of these calls internally and then ship the resulting presentation to the place where it will get integrated with the other presentation part components. It could give you the option to enjoy the benefits of spatial locality.
Another benefit that was already mentioned before is the fact that you can easily rip and replace a service. You only have to worry about the presentation and business logic layer interfaces, not about what’s actually happening behind those interfaces. Think Field Replaceable Units (FRUs) but then software.
The counter argument for presentation tier integration is that you would basically have to redo the presentation layer interfaces for every new type of presentation you are targeting. I tend to disagree, and since this is just a blog post, I’m going to try to walk away from it by just asking for some proof of that first.
In “Understanding UI Integration” from 2007, the authors provide an overview of the UI integration state of the union. They basically talk about browser plugin components, mashups, portlets and WSRP (which would be one of the ways to achieve the spatial locality benefits outlined above). However, they state this:
“Although the efforts we’ve described here are certainly useful, we believe that effective standardization similar to that of standardizing service interfaces is needed for UI integration to really take off. In general we see a lack of abstraction to conceptualize composition-oriented features in the context of UI integration.”
I think that still holds today. There might be a few initiatives to push boundaries a little further (OpenSocial comes to mind), but there is no clear direction.
So what is your opinion on this? Do you consider services having a presentation layer interface malpractice or critical to true service oriented architectures? And if you do have services offering a presentation layer interface, what principles do you have in place to keep it all organized?