Services are not applications. If you remember one thing about services, that should be it. Instead, think of services as application functions -- both in their design and in how they are leveraged to form solutions.
Each service should have a simple, specific purpose independent of other services. Follow that principle, and services can be easily abstracted into composite applications: One service can leverage others as if they were functions local to the composite app.
Such autonomy is absolutely fundamental to service design. Services should execute without dependencies, if at all possible, so you can leverage them individually, no matter how course or fine-grained they may be.
Basic service characteristics
First and foremost, services must be designed for reuse. Services should be crafted to provide both behavior and information, but should not be coded in a manner that ties them to any specific application. This rule is hard to follow for many developers because one-off software is what they’ve been doing for most of their careers. But it must be followed, or else the whole exercise is in vain.
Services must also be designed for heterogeneity, without calls to native interfaces or platforms. A service built on Linux may be leveraged by Windows, Mac, or even mainframe applications, which shouldn’t care how the service was created or what platform it’s running on.
Another basic concept is abstraction, which is the concealment of protocols, data access layers, and even security mechanisms that play no role in what the service offers to the outside world. Without abstraction, multiple service consumers could not access the same service simultaneously.
Keep in mind future service aggregation as well. Individual services often become parts of composite services. For instance, a customer validation service may be part of a customer processing service, which is part of the inventory control system.
Such potential aggregation underscores that services should be limited in scope. If your needs are more complex, write more services, don’t overload a single service. You don’t want to deploy and reuse a big, fat service to leverage just 10 percent of its functionality.
Finally, services need to be designed based on standards. Although in the world of Web services this seems like a no-brainer, many developers and architects get sloppy with standards and limit interoperability.
Five steps to service design
This handful of simple steps provide a rough outline for service design. Note that they apply to designing a new service, rather than to retrofitting a legacy application (in which case your choices will probably be more limited):
1. Start by being very clear about the purpose of the service. What will the service do, and who is the intended user? Will it be accessed by humans, applications, other services, or all of the above? Directly or indirectly?
2. Determine the information to be bound to the service, including both metadata and schema. This means you need to understand how information is leveraged by the service and what functions require what data.
3. Stipulate the functions (methods) encapsulated inside the service -- in other words, the behaviors you would like to expose. Define how each function breaks down using a traditional functional decomposition chart.