Service orientation is a business-driven “modeling strategy” that defines the business functionality in terms of loosely coupled autonomous business systems (or services) that exchange information based on messages. The term services is used in many contexts, but in the context of service orientation, a service is based on four fundamental tenets. We’ll discuss these four tenets, originally proposed by the WCF team at Microsoft, in the following sections.
Tenet 1: Boundaries Are Explicit:
Crossing boundaries is an expensive operation because it can constitute various elements such as data marshaling, security, physical location, and so on. Some of the design principles to keep in mind vis-à-vis the first tenet are as follows:
- Know your boundaries: A well-defined and published public interface is the main entry point into the service, and all interactions occur using that. Services should be easy to consume: It should be easy for other developers to consume the service. Also, the service interface should allow the ability to evolve over time without breaking existing consumers of the service.
- Avoid RPC interfaces: Instead, use explicit messages.
- Keep the service surface area small: Provide fewer public interfaces that accept a well-defined message, and respond likewise with a well-defined message. As the number of public interfaces grows, it becomes increasingly difficult to consume and maintain the service.
- Don’t expose implementation details: These should be kept internal; otherwise, it will lead to tight coupling between the consumer and the service.
Tenet 2: Services Are Autonomous:
Services are self-contained and act independently in all aspects such as deploying, versioning, and so on. Any assumptions made to the contrary about the service boundaries will most likely cause the boundaries to change themselves. Services need to be isolated and decoupled to accomplish the goal of making them autonomous.
Tenet 3: Services Share the Schema and Contract, Not the Class:
Services interaction should be using policies, schemas, and behaviors instead of classes, which have traditionally provided most of this functionality. The service contract should contain the message formats (defined using an XML schema), message exchange patterns (MEPs, which are defined in WSDL), any WS-Policy requirements, and any BPEL that may be required. The biggest challenge you face is the stability of the service, once it has been published. It gets difficult to change it then without impacting any of the consumers.
The design principles to keep in mind for the third tenet are as follows:
- Service contracts constituting data, WSDL, and the policy do not change and remain stable.
- Contracts should be as explicit as possible; this will ensure there is no confusion over the intent and use of the service. Additional contracts should be defined for newer versions of the server in the future.
- If breaking service contracts is inescapable, then version the services because this minimizes the ripple to existing consumers of the service.
- Do not expose internal data representation publicly; the public data scheme should be absolute.
Tenet 4: Service Compatibility Is Based on Policy:
At times you will not be able to express all the requirements of service interaction via WSDL alone, which is when you can use policies. Policy expressions essentially separate the structural and semantic compatibility. In other words, they separate “what is communicated” and “how/whom a message is communicated.” A policy assertion identifies a behavior of a policy entity and provides domain-specific semantics. When designing a service, you need to ensure that policy assertions are as explicit as possible regarding service expectations and semantic compatibilities.