Monday, October 8, 2012

Intelligent Design Patterns Part 2: How Service Oriented is Your Architecture?

The other day I wrote about the inherent struggle between simple and complex software design, and promised to follow that up with some specific instances from small design decisions such as whether to use the facade pattern between your web and business layers, to fundamental decisions regarding your organization's theory of software development such as Test Driven Development. Let's start the series ambitiously with the granddaddy of them all - Service Oriented Architecture (SOA).

The concept of SOA has been around for a few years now, and really took off around six years ago when SOAP web services were saturating the development landscape, and Microsoft introduced WCF. Though strict adherence to SOA principles has declined as PM's have realized some of it's drawbacks, the theme of services has remained strong, and promises to do so with an ever growing suite of tools such as Microsoft's new MVC 4 Web API.

Why Not SOA?

If you are thinking about whether or not to build your next enterprise application using SOA, make sure to answer some of the questions above, because there are some very real negative implications to SOA. Your application will be slower and will take longer to design, code, and test than a similar three tier architecture that is wholly contained on a web server. This is not an accident, and in fact it is freely admitted and even highlighted as part of the SOA Manifesto. (Editor's note: no I did not just make that up. There really is a SOA Manifesto.) The speed and initial development cost of your particular application is not the priority of SOA:

Through our work we have come to prioritize:
Business value over technical strategy
Strategic goals over project-specific benefits
Intrinsic interoperability over custom integration
Shared services over specific-purpose implementations
Flexibility over optimization
Evolutionary refinement over pursuit of initial perfection 
From the SOA Manifesto


I started to make a table to translate each of those principles into the real-world consequences to your project, but started repeating myself quite a bit as nearly all of these principles mean that your code will be (a) harder to write or (b) perform more slowly at run time in order to facilitate as-yet-unknown future business needs.

Does this mean that SOA is a flawed concept that should be relegated to the annals of history like a well loved pair of hammer pants? No, of course not, but it does mean that if you are going to use SOA (or any layer of abstraction or non-trivial design pattern for that matter) you'd better have a very solid reason because complex, modularized, layered architectures can get very tricky very fast if left unchecked.

If you're not careful, your SOA will turn into this SOA.












In the list of key questions design from our original post, SOA seeks to answer one of them: How will external applications consume my solution's data? When you boil it down, the guiding philosophy behind SOA is to allow external systems to obtain my application's data and/or business logic without connecting directly to my database (if you have another reason, let me know, because I haven't seen another valid one. I've never seen arguments around loose couplingflexibility, or out-of-the-box reusability actually work in the wild. If your application needs to support standard browsers, heavy clients, mobile clients, etc, SOA used to be the way to go, but I think that oftentimes we can achieve this type of multi-platform support more effectively and cheaply with proper use of the MVC pattern, especially with newer technology patterns such as Web API. More on this in a later post.

A fairly standard SOA implementation
For the purposes of this discussion, let's assume we are talking about a web application, where SOA involves,

  • a web layer that communicates to an application layer in some sort of over-the-wire protocol such as SOAP, JSON based web services, WCF, etc, 
  • which exposes an API, 
  • which wraps a business logic layer, 
  • which calls into a Data Access Layer, 
  • which in turn calls the database. 

Before we go any further, I need to note that when I discuss whether or not to use SOA, I am not debating whether or not to remove the BL or the DAL layers, but rather whether or not to insert a web service between the web layer and the BL layer.

The first question we need to ask is whether or not any external applications will, in the foreseeable future need to consume my application's data. If the answer is "No", then don't use SOA. Don't do it, it's not worth it. It will cause you more heartache and grief than any imagined benefits you can write on your whiteboard. I'm serious.

If other systems will need to use your business logic or data, then SOA is the way to go, right? Well... not necessarily. How exactly will your system need to use your data? In the vast majority of cases in the enterprise world, when your peers in the financial application development group three cube rows need access to your data, they don't need to see all the details of the functionality of your system. They won't need to add or remove users. They don't want to know the complete list of lookup values for sales order status. They certainly don't want or need access to your logging logic, and they really don't want to have to worry about sessions. What they usually need a simple dump of your data. In the cases where a member of the data warehouse, finance, marketing, legal, IT Ops, or Double Secret Probation Tiger Team for Special Projects simply needs to see your data, you have several options. I've compiled a general list below in order of cost to you're project's budget:
  1. Build a damn view in your database containing exactly what they need to see and nothing else
  2. Create a one-off ETL process in SSIS, Informatica, a simple console app running a stored procedure, etc
  3. Create a one-off HTTP method, either using a custom handler (.NET), a stand alone simple web service method, a custom controller, single WCF service, etc*
  4. Rearchitect your entire application to use SOA for all interactions between your web and business layer, including the 99%** of transactions that the other application does not care about 
*   This method is necessary if the external application needs access to business logic not contained in your database.
** Actually, it's quite possible that the other application needs it's own unique view of the data, meaning that it doesn't care about 100% of the methods in your service, and you just need to create a custom method anyway.

Is SOA Ever a Good Idea?


OK, so I've almost talked myself into SOA being a bad idea in every circumstance. That's not the case, however. SOA, in my experience, ends up being more costly than it's worth in the vast majority of enterprise scenarios, but there are very important scenarios where SOA is exactly the right architecture for the job at hand. Now we could talk about interface points, parallel layers, or autonomous processing, but generally most case studies where SOA really works fall into one or both of the following categories:

  1. The user interface isn't the key portion of the application
  2. You will release a programming API for outside consumers

When the UI Isn't King

TFS loves it some services since 2005

Most of the applications we write serve the purpose of recording and delivering information from user to user through a common database using a single user interface, whether it be a web application, desktop application, or mobile application. There are many systems, however, that aren't focused on the end user experience, and are instead more focused on interacting with other applications rather than the end user. A good example is Microsoft's Team Foundation Server (TFS). TFS has a very robust user interface for the web, a standalone client, and through Visual Studio. However, it's main purpose in life is not to interact with the user - it's primary purpose is to manage resources: work items, source files, and builds. These tasks lean very heavily on machine to machine interactions, and the user interface is mostly a view into those interactions. In this case, could you imagine the architecture based around anything but an application server? A user facing web server as the focal point would simply not make sense. (Note, an application server can still be built around IIS, Tomcat, etc, but it can only expose machine to machine services using HTTP as a protocol. It does not serve web pages).

When You're Sending Your Baby Into the World

Sometimes the application you're writing is almost too awesome to handle. You can't keep it in, you need to share it's gorgeous functionality with the world, who you expect to have its way with it and produce beautiful baby mash-ups featuring the marvelous code-seed that is your application. It may be stating the obvious, but in this case you need to provide some services for these applications to hook into. If you want these services to match what the users see from the application itself and not produce maddening inconsistencies between your web app and its API, then SOA can guarantee that the functionality is consistent (assuming proper construction that keeps business logic out of your web layer). This scenario actually dovetails nicely with the one above: how does TFS ensure that the web viewer is consistent with the Visual Studio plugin, which is in turn consistent with the public facing API? Simple, they all run on the same services.


SOA can be a powerful tool if you're looking to build a truly distributed system that is able to integrate with many players throughout your organization, but it comes with many associated costs. You need to ask yourself several questions before deciding to use an SOA - What will it bring to my project? What additional costs will I incur? Are there simpler methods of achieving these goals? Remember, you are putting your credibility on the line when you make an architectural decision. If you choose to use a more complicated architecture than necessary and it ends up burning you, your PM is going to regard your next design decision with a very skeptical eye. I used the Einstein quote in the first post in this series, and I'll use it again now:

Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. - Einstein

No comments:

Post a Comment