The term “SOA” is surrounded by hype, hyperbole, and generality. You want a definition that you can work with.
You must define SOA with some modicum of care before proceeding in order to set expectations appropriately. This is made somewhat difficult given the avalanche of hype surrounding SOA in recent years. But it can be done. There are many possible definitions of SOA. Here is my offering:
SOA is a kind of architecture that uses services as building blocks to facilitate enterprise integration and component reuse through loose coupling.
Let’s unpack that a little bit, shall we?
While this is perhaps overstating the obvious, there is a small lesson here. Simply creating a set of services does not automatically render an architecture. Architecture, while it should guide the creation of services, is a diverse matter separate from the implementation of the services themselves.
In the term “SOA,” “service-oriented” modifies “architecture” as an adjective. That is, an SOA describes a sort of architecture one can undertake. It is not a development mode. You cannot simply annotate an EJB to indicate that it’s a web service and decide that because you now have a web service, you must have the felicitous beginnings of an SOA. If you are not very careful with your approach, you could indeed have the beginnings of a very elaborate, very expensive mess.
One point that must be made is that you cannot simply buy an SOA. You cannot expect a single vendor to hand over an SOA once your CIO writes a check. Building an SOA involves considerable analysis and integration.
This is the “service” part of “service-oriented architecture” and I rely here on my definition in Defining a Service. It’s not an SOA if it’s not an architecture, or if that architecture doesn’t use the service as the common unit of measure (just as an object-oriented system uses the object or class as its common unit).
Without services, there is nothing to build on, monitor, or govern, and nothing to execute to provide your business value. But at the other extreme, one can labor long and hard, producing a perfectly lovely set of architectural diagrams with little relation to the real world. If you focus narrowly on cranking out a set of service implementations and forget the architecture—or, more likely, leave it out on purpose while dismissing the “astronaut architects” with their heads in the clouds—you will not only have no SOA, but you’ll have something even worse. You will have spent considerable time and money over-engineering a solution to the wrong problem. There is actually a name for this sort of furious work: the anti-pattern known colloquially as Just a Bunch of Web Services (JaBoWS). In addition, cowboy developers operating without architectural guides can inadvertently cause the business to fall prey to another SOA anti-pattern: Rogue Service, wherein there are services operating on the network that are not part of the known, governed set of services in the catalog. So a bunch of services without architecture or governance does not an SOA make.
In my view, it is debatable whether a “service” that is wholly outside the context of an architecture is actually a service at all. It is in part the contextual role within a supporting architecture that elevates an operation to the level of a service. This status is afforded, but not directly stated, by the last criterion in my definition of a service: it can be decorated with runtime extensions that handle certain technical non-functional requirements.
SOA represents a way of thinking about systems integration. An SOA serves to offer increased or new business functionality or opportunities by connecting multiple systems together. In its most straightforward form, this means that you can do B2B work more quickly.
CORBA, connector architecture, EDI, and point-to-point EAI efforts over decades have all demonstrated the ability to integrate diverse systems. But such efforts can be costly and brittle. They can distract developers and IT departments from addressing their real business problems, as they work for months getting systems to talk. These solutions all define their own formats for message exchange. SOA, in general, reuses XML as a standard means of message format, allowing integration efforts to leap into action more readily.
Some CIOs, in frustration with previous EAI projects and in an honest attempt to address their problems quickly and decisively, have thrown in the towel, called up their favorite vendor, and signed up for their entire stack in an attempt to avoid the integration problem altogether. But this can be a very expensive proposition indeed and it has the drawback of tying your organization to that vendor, locking you into operating on their time tables, and you’ll be able to provide only the functionality they expose.
So while integration happens, SOA attempts to address the pain points of integration efforts.
The idea that SOA facilitates reuse through loose coupling is a key modification of the point that it simply supports enterprise integration efforts. SOA suggests two distinct ideas: it facilitates reuse in the first place, and it does so by creating loosely coupled components.
Early enterprise integration or primitive service provider efforts have not focused quite so specifically on the idea of reuse. But it is now possible, given the new standards and the employment of a generic format such as XML in message exchanges, to realize enterprise services in a sufficiently general way that services can be reused.
This reuse can come in the form of general interoperability. If two software components can interoperate, that in no way means they are loosely coupled. But loosely coupled components have a greater chance of interoperating.
One of the foundational aspects of SOA is that services are created from the ground up with the intention of having them interoperate with unforeseen or unknown components. This makes a sharp distinction from typical integration efforts, which likely target a single set of known interfaces.
While reuse can be achieved as a side effect of ensuring that your services are loosely coupled, it is not a necessary aim for every service. It is possible that you have certain services that you know have little likelihood of being reused in a composition or within an unforeseen business context. Such services may have been created as pilot projects; or it may have made sense given the circumstances to create some functionality as a service in order to tap into a larger architectural infrastructure to make it more visible, for example, through a service inventory; or to take advantage of centralized schemas; or to quickly gain runtime metrics afforded by SOA monitoring tools.
Reuse is not strictly necessary within any given service. However, an SOA entirely populated by non-reusable components is likely not an SOA at all, but rather a fancy, bloated, over-engineered collection of point-to-point EAI dinosaur bones.
Be careful allowing a service to directly invoke another service (that is, to have itself be the client of that service), as this can strikingly reduce the business contexts available for reusing the service. Sometimes it seems necessary to make one service the client of another service within its implementation. But you are introducing a degree of coupling here that you might not want later. If you find yourself in this situation, consider using an orchestration technology such as BPEL (covered in Chapters 9 and 10).
Also, it can be difficult without service-level agreement (SLA) monitoring software and metrics in place to keep track of how much traffic a service is receiving from where. If your service crosses business domains, it becomes particularly important to consider that it could see sudden, unexpected explosions in traffic due to compositions external to your current subject. Another problem with direct invocation is that it adds complexity to your topography without allowing visibility through tools. There are tools by the big SOA suite vendors that show dependencies across the service-related resources stored in your enterprise repository, but they can be very expensive.
The architectural solution to this problem is that when you want to have one service directly invoke another, consider whether you can create an orchestration (or process service, as defined in Identifying Different Kinds of Services) instead. As a service wraps a system or subsystem, an orchestration wraps a set of services that together make a flow. But the orchestration is itself exposed as a service, so it looks just like any other service to the client.