It is defined by an interface that may be platform-independent.
It is available across a network.
The operations defined in the interface carry out business functions by operating on business objects.
Its interface and its implementation can be decorated with extensions that come into effect at runtime.
A service can mean other things as well. Sometimes the definition is broader, to include, for example, a distributed component whose interface is designed by the business. Sometimes the definition is more narrow, such as a SOAP-based web service.
One initial difficulty in approaching SOA is that people don’t always agree on what is meant by its fundamental building block, the service. Many definitions of a service refer to slippery or very abstract concepts, such as “adaptability” and “agility,” that are too vague to be useful to the developer. Presumably, given the choice, no one wants to make unadaptable, leaden software that doesn’t meet business needs. But the fact of the matter is that, despite best efforts, this happens all too often. Knowing that SOAs should be “adaptable” and “agile” may be laudable, but that alone doesn’t help make a state change. Let’s unpack these terms a bit.
Other definitions are too narrow for the real world. It is tempting, for example, to indicate that a service must be a software component that talks SOAP. But this limitation is artificial; there are many practitioners using REST who believe, quite reasonably, that they are doing services. Perhaps our definition should include something about messages being XML-based, as this is a common denominator between RESTful web services and SOAP-based services. But this is also too limiting for a general definition.
So how do you arrive at a definition that is specific enough to be useful and yet general enough to admit the wide variety of approaches that people take in the real world?
Let’s examine each aspect of the service definition before proceeding.
The work a service can do must be described with an external interface. Some architects allow that such an interface can actually be tied to a specific platform, as in the case of a Java interface describing the operations on a remote session EJB. Services can certainly be approached in this manner, and such an approach may be justified within a given business context. Dictating that consumers must use a certain platform, such as Java or .NET, to consume a service can save valuable time and money and drastically simplify your implementation.
Many SOAs operate within a company, behind a firewall, in a known environment that is relatively static. I have talked with architects in such circumstances whose entire SOA is defined on EJB. That’s a very specific platform, and they think they are doing SOA, and they are smart and experienced people.
Their view is that it would introduce unwarranted developer effort, offer more complexity than benefit, and garner unnecessary runtime overhead to use SOAP and its many attendant specifications given their business context. So while many authors are tempted to indicate that a service must be defined in a manner that does not dictate platform, and while that sort of service is the chief topic of this book, my definition does allow for platform-specific implementations.
However, a service is generally created to address a systems integration problem, or at least has an eye toward integration issues. A WSDL is one way to describe functionality in a way that does not dictate implementation. While WSDLs may commonly use SOAP over HTTP, this is not a requirement; other protocols can be used for bindings, and the same abstract WSDL can address a variety of bindings, offering even greater flexibility.
HTTP is perhaps not the ideal transport layer for web-based services, but its simplicity and pervasiveness have made it the default choice. Consequently, there is considerable support for such service implementations.
RESTful web services use XML and native HTTP methods to define their interfaces, and this approach has many proponents who cite the complexity and “bloat” of SOAP-based services. I want to avoid this argument for now, and just indicate that REST sufficiently satisfies the condition of platform independence. It is less clear that it satisfies an emphatic interface that can operate as part of a service contract, however.
Because a service is not merely a piece of functionality, but something describable by a contract that constrains consumers, it is important that a clearly defined interface work within contract automation. Without a clear interface, service reusability opportunities shrink. Without platform independence, possible consumers go down and service components become more tightly coupled.
Of course, nothing is free, and you pay for platform independence with performance and complexity.
The world is filled with very useful programs whose functions can be invoked only from within the same virtual machine or within the same physical machines. These programs simply do not qualify as services. Just as in the real world, your customers have to be able to contact your business to contract for your cleaning or consulting or catering services. If you’re the only one who knows your phone number, or if you don’t have a phone, then there’s no show. If your function is not available remotely, it is simply not a service.
My third criterion for a service is that it generally carries out business functions, and generally does so by operating on business documents. What does this mean? A calculator that adds two numbers together may not be a good candidate for a service because integers are not business objects. They can never be defined in a particular way for your organization.
A “business object” means an instance of an entity in your business domain,
such as a Customer, a Product, an Invoice, a Student, or an
Application for Employment. You can decide for yourself what these
will mean, as they are the entities that differentiate your business
from others. Further examination of your
must question whether the idea of adding is particular to your
business. It is not. Anyone in the world can add all day long, and
will do so (presupposing any basic mastery of the task) in a manner
identical to everyone else. Moreover, you have no opportunity for
innovation in the method in which you add; you cannot conceive of and
employ some custom scheme for adding within your operation’s
implementation to gain a competitive advantage in the market. Unless
you have a very creative accounting department, you don’t decide for
yourself what integers and adding mean.
There is certainly a wide array of popular services publicly available that operate on facts. These include determining the distance from one location to another, or performing calculations such as shipping costs based on weight, or finding the location of the nearest store. While a zip code or a weight in ounces may not in themselves appear to be business objects, such services do perform a business operation that is distinguishable from something absolutely generic such as adding two numbers together.
This is just a general guideline. Consider a service that converts currency. There are many such publicly available web services, and a euro is the same for everyone, so these don’t appear to be business objects. But there is always the matter of perspective. At a bank, the idea of currency might be considerably more detailed in its definition than it is at a pet food store, making it a kind of business object to the bank.
There are always exceptions to the rule. The idea here is to think in terms of services exchanging business documents, rather than accepting lists of simple values.
You probably don’t need an SOA if you don’t have a business of some size, or at least of some length of history. While programmers might enjoy writing a video game for their own personal use, no one builds an SOA out in the garage on Saturday afternoons. If you’re talking about an SOA, you’re talking about a business of some measure. And your SOA will realize its potential ROI (return on investment) if its constituent services operate at the appropriate level of granularity in order to maximize their reuse. Of course, this begs the question what is meant by “appropriate level.” That will depend on the business processes that define your services, and what related processes might be able to reuse them.
I must stress that this guideline is open to a wide variety of interpretations, and is presented as a starting point so that you can make some distinctions. You want to avoid being so vague that you do not have enough to work with. Indeed, there are utility or functional services that operate in the realm of technology alone; these are described in Identifying Service Candidates.
This refers to the idea that you must be able to decorate the service operation in some way in order to provide for functional and non-functional requirements. It is this aspect that elevates the service to something meaningful with an SOA.
If you are using SOAP, a variety of WS-* specifications (such as WS-ReliableMessaging or WS-SecureConversation) add capabilities to your service that do not impact the core business functionality, but make your service adaptable for use within an SOA. The ability to add HTTP headers, for example, is one way of decorating a REST-based service implementation. EJBs make the cut because, while the mechanism is not based on WS-* standards, interceptors do allow for decoration of like functionality.
The point here is that you want to be able to provision your SOA, and by necessity its constituent services, with technical means of governance (which we will discuss later). You want to be able to include policies at runtime that augment how the service can be used. The ability to interact securely, to allow for transactional operations, and, in some cases, to accept monitoring instrumentation are non-functional requirements that bridge the gap between a theoretically pure implementation of your Invoice Processing service and the real world that involves this particular network with these external constraints that must be accounted for. Baking such items into your service can severely curtail or obliterate its possibilities for reuse, especially in federated environments. But the need to deal with them remains; when possible, move such requirements into decorators.
This requirement may guide your choice of platform or implementation. The fact that there are so many non-functional requirements that so often come into play in software components (and the fact that so many of them are recognized by WS-* specifications) is a leading reason why I have chosen to focus on SOAP-based services in this book (and in building a real-world SOA). To have such common requirements dealt with in a standard way within these specs offers a boost to interoperability and maintainability, and allows developers to focus on their business problem.
What else might be true of the operation if it is to qualify as a service? It seems that a service is worth all the trouble to define and create only if it will be reused. A chief aim of SOA is that its components are self-contained and do not represent overlapping functionality. Its components should provide a degree of reusability. That is, they must not be limited to a narrowly defined business context that has little or no relevance elsewhere in the enterprise. It is possible that you will write a service that does not get reused. It is possible that your business will change directions, or that a service is too poorly defined, either too granular or too broad in scope, to ever fit into another use case. Sniffing out such matters is where architects are valuable.
Some architects will add the requirement that a service must be stateless. I agree that in general it is a good idea to ensure that your service operations are stateless, but I would not require it as a defining feature of services. If they must maintain state, they can do so externally through a database or other temporary serialization mechanism. Conversational state is often best avoided if possible, but when it must be maintained within the service composition, it can be handled through a specification such as WS-SecureConversation and WS-Conversation. This is a spec that has been around for a few years now, and is implemented in containers like WebLogic 10gR3.