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 such details. 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. This tenet is the modern incarnation of the old object-oriented adage that the application should maximize encapsulation and information hiding.

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, enabling it to evolve separately from them. The service should also be secured independently, so it can protect itself and the messages sent to it regardless of the degree to which the client uses security. Doing this (besides being common sense) further decouples the client and the service.

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

What the service decides to expose across its boundary should be type-neutral. The service must be able to convert its native data types to and from some neutral representation and should 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 those 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 the need for reliable communication) should be separate from the service implementation details. 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 poor service design. Note that a non-public service may not actually publish any such policy. This tenet simply implies that the service should be able to publish a policy if necessary.

Practical Principles

Well-designed applications should try to maximize adherence to the tenets just listed. However, those tenets are very abstract, and how they are supported is largely a product of the technology used to develop and consume the services, and of the design of the services. Consequently, just as not all code written in C++ is fully object-oriented, not all WCF applications may fully comply with the basic tenets just described. I therefore supplement those 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 messages from the clients 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 in a consistent state after the client’s call. If an error occurs the system state should not be only partially affected, and 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 and logical thread reentrancy.

Services are reliable

If the client calls a service, the client will always know in a deterministic manner whether the service received the message. In-order processing of messages is optional.

Services are robust

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

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 any client, regardless of its technology, can call it.

Services are scale-invariant

It should be possible to 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 clients’ requests and should have no downtime. Otherwise, if the service has periods of unavailability, the client needs to accommodate them, which in turn introduces coupling.

Services are responsive

The client should not have to wait long for the service to start processing its request. If the service is unresponsive the client needs to plan for that, which in turn introduces coupling.

Services are disciplined

The service should not block the client for long. The service may perform lengthy processing, but only as long as it does not block the client. Otherwise, the client will need to accommodate that, which in turn introduces coupling.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.196.175