Tenet 1: Boundaries are explicit
Services interact by sending messages across boundaries. These boundaries are formal and explicit. No assumptions are made about what is behind boundaries, and this preserves flexibility in how services are implemented and deployed.
- Know your boundaries.
- Provide few well-defined public interfaces to your service.
- Internal (private) implementation details should not be leaked outside of a service boundary.
- Services should be easy to consume.
- Crossing a boundary can be expensive. SOA urges discipline in what is exposed to a boundary. It’s important to call services only when necessary and to do so as simply and efficiently as possible.
- Avoid RPC interfaces because this can lead to an overuse of calls. Accessing a service is not the same as accessing a local object!
Tenet 2: Services are autonomous
Services are not subservient to other code: a service reacts to a message – how that message was created and what will happen to any response the service creates is immaterial to the action that this service will take.
- Deploy and version services independently from the clients. Hence, services can evolve separately from the clients.
- Design contracts with the assumption that once published, they can’t be modified. Build flexibility into the schema design.
- Design services by adopting a pessimistic outlook. From a provider perspective, expect misuse of the service. From a consumer perspective, plan for unreliable levels of service availability and performance.
Tenet 3: Services share schema & contract, not class
Only messages pass from service to service, code does not. These messages are not random but a sequence of one or more that have been agreed upon.
- A service’s contract should remain stable to minimize impact upon service consumers.
- Contracts should be designed to be as explicit as possible to minimize misinterpretation.
- Avoid blurring the line between public and private data representations. A service’s internal data format should be hidden from consumers, while its public schema should be immutable.
- A service must be able to convert its native data types to and from some technology-neutral representation. No technology-specific things are exposed!
- Version services when changes to the service’s contract are unavoidable.
Tenet 4: Service compatibility is based upon policy
A service must be able to express in a standard representation of policy what it does and how clients should communicate with it.
Services don’t just blindly access each other: they need to determine areas of compatibility and agree on how they will interact. Every service provides a policy – a machine-readable description of its capabilities and requirements.
Each service has a set of policies that it expects to operate under and it is not prepared to operate unless these policies are satisfied.
Using policies allows the behavior of a service to be separated from the constraints of accessing the service.
- Policy assertions should be as explicit as possible regarding to service expectations and service semantic compatibilities.