Section A.3. Tenets and Principles


A.3. Tenets and Principles

The service-oriented methodology governs what happens in the space between services (see Figure A-1). There is a small set of principles and best practices for building service-oriented applications referred to as the tenets of service-oriented architecture:


Service boundaries are explicit

Any service is always confined behind boundaries such as technology and location. The service should not make the nature of these boundaries known to its clients by exposing contracts and data types that betray its technology or location. Adhering to this tenet will make aspects such as location and technology irrelevant. A different way of thinking about this tenet is that the more the client knows about the implementation of the service, the more the client is coupled to the service. To minimize the potential for coupling, the service has to explicitly expose functionality, and only operations (or data contracts) that are explicitly exposed will be shared with the client. Everything else is encapsulated. Service-oriented technologies should adopt an "opt-out by default" programming model, and expose only those things explicitly opted-in.


Services are autonomous

A service should need nothing from its clients or other services. The service should be operated and versioned independently from the clients. This will enable the service to evolve separately from the client. The service is also secured independently and it protects itself and the messages sent to it regardless of the degree to which the client uses security. Doing so (besides being just common sense) also decouples the client and the service security-wise.


Services share operational contracts and data schema, not type- and technology-specific metadata

What the service does decide to expose across its boundary should be technology-neutral. The service must be able to convert its native data types to and from some neutral representation, and does not share indigenous, technology-specific things such as its assembly version number or its type. In addition, the service should not let its client know about local implementation details such as its instance management mode or its concurrency management mode. The service should only expose logical operations. How the service goes about implementing these operations and how it behaves should not be disclosed to the client.


Services are compatible based on policy

The service should publish a policy indicating what it can do and how clients can interact with it. Any access constraints expressed in the policy (such as reliable communication) should be separate from the service implementation details. Not all clients can interact with all services. It is perfectly valid to have an incompatibility that prevents a particular client from consuming the service. The published policy should be the only way that clients decide if they can interact with the service, and there should not be any out-of-band mechanism by which the clients make such a decision. Put differently, the service must be able to express, in a standard representation of policy, what it does and how clients should communicate with it. Being unable to express such a policy indicates a poor design of the service. Not that the service may not actually publish any such policy due to privacy (if it is not a public service). The tenet implies that the service should be able to publish a policy if it needs to.

A.3.1. Practical Principles

The tenets just listed are very abstract, and supporting them is largely a facet of the technology used to develop and consume the services and the design of the service. Consequently, applications may have various degrees of compliance with the tenets, much the same way as developers can write non-object-oriented code in C++. However, well-designed applications try to maximize adherence to the tenets. I therefore supplement the tenets with a set of more down-to-earth practical principles:


Services are secure

A service and its clients must use secure communication. At the very least, the transfer of the message from the client to the service must be secured, and the clients must have a way of authenticating the service. The clients may also provide their credentials in the message so that the service can authenticate and authorize them.


Services leave the system in a consistent state

Conditions such as partially succeeding in executing the client's request are forbidden. All resources the service accesses must be consistent after the client's call. A service must not have any leftovers as a result of an error, such as only partially affecting the system state. The service should not require the help of its clients to recover the system back to a consistent state after an error.


Services are thread-safe

The service must be designed so that it can sustain concurrent access from multiple clients. The service should also be able to handle causality or logical thread reentrancy.


Services are reliable

If the client calls a service, the client will always know in a deterministic manner if the message was received by the service. The messages should also be processed in the order they were sent, not in the order they were received.


Services are robust

The service isolates its faults, preventing them from taking down itself or other services. The service should not require the clients to alter their behavior according to the type of error the service encountered. This helps to decouple the clients from the service on the error-handling dimension.

A.3.2. Optional Principles

While I view the practical principles as mandatory, there is also a set of optional principles that may not be required by all applications, although adhering to them as well is usually a good idea:


Services are interoperable

The service should be designed so that it can be called by any client, regardless of its technology.


Services are scale-invariant

They should use the same service code regardless of the number of clients and the load on the service. This will grossly simplify the cost of ownership of the service as the system grows and allow different deployment scenarios.


Services are available

The service should always be able to accept the client's requests, and the service should have no downtime. Otherwise, if the service is unavailable, the client needs to accommodate for that, which in turn introduces coupling.


Services are responsive

The client should not wait long for the service to start processing its request. Having a nonresponsive service means the client needs to accommodate for that, which in turn introduces coupling.


Services are disciplined

The service execution of any operation is relatively short and does not take long to process the client's request. Having long processing means the client needs to accommodate for that, which in turn introduces coupling.




Programming WCF Services
Programming WCF Services
ISBN: 0596526997
EAN: 2147483647
Year: 2004
Pages: 148
Authors: Juval Lowy

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net