Saturday, July 31, 2010

Consumer-Driven Contracts


The use of Schematron in the above example leads to some interesting observations about contracts between providers and consumers, with implications beyond document validation. In this section we draw out and generalize some of these insights and express them in terms of a pattern we call Consumer-Driven Contract.

The first thing to note is that document schemas are only a portion of what a service provider has to offer consumers to enable them to exploit its functionality. We call the sum total of these externalized exploitation points the provider contract.

Provider Contracts

A provider contract expresses a service provider's business function capabilities in terms of the set of exportable elements necessary to support that functionality. From a service evolution point of view, a contract is a container for a set of exportable business function elements. A non-normative list of these elements includes:

Document schemas We've already discussed document schemas in some detail. Next to interfaces, document schemas are the parts of a provider contract most likely to change as the service evolves; but perhaps because of this, they're also the parts we have most experience of imbuing with service evolution strategies such as extension points and document tree path assertions.
Interfaces In their simplest form, service provider interfaces comprise the set of exportable operation signatures a consumer can exploit to drive the behaviour of a provider. Message-oriented systems typically export relatively simple operation signatures and push the business intelligence into the messages they exchange. In a message-oriented system, received messages drive endpoint behaviour according to semantics encoded in the message header or payload. RPC-like services, on the other hand, encode more of their business semantics in their operation signatures. Either way, consumers depend on some portion of a provider's interface to realise business value, and in consequence we must account for interface consumption when evolving our service landscape.
Conversations Service providers and consumers exchange messages in conversations that compose one or more message exchange patterns such as request-response and fire-and-forget. Over the course of a conversation a consumer may expect the provider to externalize some state particular to the interaction in the messages that it sends and receives. For example, a hotel reservation service might offer consumers the ability to reserve a room at the outset of a conversation, and to confirm the booking and make a deposit in subsequent message exchanges. The consumer here might reasonably expect the service to "remember" the details of the reservation when engaging in these follow-on exchanges, rather than demand the parties repeat the entire conversation at each step in the process. As a service evolves, the set of conversational gambits available to provider and consumer might change. Conversations are thus candidates for being considered part of a provider contract.
Policy Besides exporting document schemas, interfaces and conversations, service providers may declare and enforce specific usage requirements that govern how the other elements of the contract can be realised. Most commonly, these requirements relate to the security and transactional contexts in which a consumer can exploit a provider's functionality. The Web services stack typically expresses this policy framework using the WS-Policy generic model plus additional domain-specific policy languages such as WS-SecurityPolicy, but in the context of our considering policies as candidates for being included in a provider contract, our definition of policy is specification and implementation agnostic.
Quality of service characteristics The business value potential that service providers and consumers exploit is often evaluated in the context of specific quality of service characteristics such as availability, latency and throughput. We should consider these characteristics as likely constituents of a provider contract and account for them in our service evolution strategies.
The definition of contract here is a little broader than the one we might usually offer when talking about services, but from a service evolution perspective it usefully abstracts the significant forces that impact our problem domain. That said, the definition is not meant to be exhaustive in terms of the kinds of elements a provider contract might contain: it refers simply to a logical set of exportable business function elements that are candidates for including in a service evolution strategy. From a logical point of view, this set of candidate elements is open, but in practice internal or external factors, such as interoperability requirements or platform limitations, may constrain the type of elements a contract can contain. For example, a contract belonging to a service that conforms to the WS-Basic profile will likely not contain policy elements.

Notwithstanding any such constraints, the scope of a contract is determined simply by the cohesion of its member elements. A contract can contain many elements and be broad in scope, or focus narrowly on only a few, just so long as it expresses some business function capability.

How do we decide whether to include a candidate contractual element in our provider contract? We do so by asking ourselves whether any of our consumers might reasonably express one or more expectations that the business function capability encapsulated by the element continue to be satisfied throughout the service's lifetime. We've already seen how consumers of our example service can express an interest in parts of the document schema exported by the service, and how they might assert that their expectations regarding this contractual element continue to be met. Thus, our document schema is part of our provider contract.

Provider contracts have the following characteristics:

Closed and complete Provider contracts express a service's business function capabilities in terms of the complete set of exportable elements available to consumers, and as such are closed and complete with respect to the functionality available to the system.
Singular and authoritative Provider contracts are singular and authoritative in their expression of the business functionality available to the system.
Bounded stability and immutability A provider contract is stable and immutable for a bounded period and/or locale (see the section "Validity of Data in Bounded Space and Time" in Pat Helland's paper Data on the Outside vs. Data on the Inside). Provider contracts typically use some form of versioning to differentiate differently bounded instances of the contract.
Consumer Contracts

If we decide to account for consumer expectations regarding the schemas we expose when evolving our service - and consider it worth our provider knowing about them - then we need to import those consumer expectations into the provider. The Schematron assertions in our example look very much like the kinds of tests that, if implemented by the provider, might help ensure the provider continues to meet its commitments to its clients. By implementing these tests, the provider gains a better understanding of how it can evolve the structure of the messages it produces without breaking existing functionality in the service community. And where a proposed change would in fact break one or more consumers, the provider will have immediate insight into the issue and be better able to address it with the parties concerned, accommodating their requirements or providing incentives for them to change as business factors dictate.

In our example, we can say that the set of assertions generated by all consumers expresses the mandatory structure of the messages to be exchanged during the period in which the assertions remain valid for their parent applications. If the provider were possessed of this set of assertions, it would be able to ensure that every message it sends is valid for every consumer insofar as the set of assertions is valid and complete.

Generalizing this structure, we can distinguish what we have already called the provider contract from the individual contractual obligations that obtain in instances of provider-consumer relationships, which we will now call consumer contracts. When a provider accepts and adopts the reasonable expectations expressed by a consumer, it enters into a consumer contract.

SOURCE:http://martinfowler.com/articles/consumerDrivenContracts.html

No comments:

Post a Comment