Special thanks to Stefan for thoroughly reviewing a draft of the article, Dan North for helping shape an even earlier version, and Jim Webber and Ian Cartwright for lots of conversation and encouragement.

I’ve still not written much on how to implement consumer-driven contracts, but I’ve something special cooking (slowly) in that area: expect some illustrative material to emerge over the next few months.

We iterate over this model many times in the course of an engagement, emphasising different parts as we go. We concentrate on organisation-level stories and capabilities when establishing an organisation-wide context, then project-level stories, capabilities and services whilst planning projects and delivery streams, and then release- and iteration-level artefacts during specific instances of delivery.

Such an approach represents a “thin-slice” way to:

establish context, business goals and consensus amongst stakeholders;

create a long-term vision that joins up the business, architectural and technology views of an SOA initiative;

describe and challenge an organisation’s goals and the benefits attached to those goals;

describe the capabilities needed to meet those goals;

identify the quality-of-service expectations the business has of those capabilities;

identify services and assign capabilities to services;

describe and test the externally visible interactions between services;

identify, plan and develop slices of service functionality that deliver business benefits early and often.

In preparation for the launch of the ThoughtWorks Anthology, each of the authors recorded a short podcast in which they discuss their essay. Mine is online now. It’s four minutes tops – the perfect aural companion as you huddle outside with a cigarette.

If you like that, you might like this: a couple of years ago, Martin Fowler and I did an interview with Microsoft’s Ron Jacobs on the Evolution of Architecture. As per usual, I’m a one-note band…

By distinguishing between provider and consumer contracts we make explicit the fact that one half of the provider-consumer relationship ought to be able to change without inducing a corresponding change in the other half – within limits. Providers ought to be able to evolve their contracts without obliging their consumers to change – just so long as they continue to satisfy existing obligations. Consumers ought to be able to modify their consumption of a provider’s existing services without requiring either that their peers change or that the provider itself be updated – up to the point they require new functionality of the service provider.

These limit cases suggest that our concerns here are not so much separated as separating. What prevents an absolute separation is the very thing that constitutes some measure of success for any distributed system: good services are used, and in being used, become a “victim” of their own success. These limits to the separation of concerns are surfaced as a third type of contract: the consumer-driven contract. Such contracts measure the success of a service, insofar as they catalogue its obligations, whilst at the same time describing when and where a variation in concern A (the provider contract) will induce a change in concern B (one or more consumer contracts).

Service Indirection

Another question I sometimes get asked is: aren’t your three contracts really only applicable in point-to-point scenarios, where consumers communicate directly with a service provider?

It’s important here to distinguish between the accountability of a service and its location. As a consumer of services, I tend to want to delegate my business to providers I trust, even if I don’t quite know where the specific person, department or office dealing with my request is located. Accountability in this instance is really shorthand for my ability to determine whether a provider is capable of satisfying my functional and quality-of-service requirements, and thereafter to demand traceability of it in respect of any requests I make. I’d be foolish to delegate my interests to some anonymous party I know nothing about, and from whom I can’t secure a guarantee of accountability, which is why I tend to draw back from an SOA-ad-absurdum that encourages me to fling messages into the “cloud,” to be satisfied by “something,” “somewhere.”

The key point here is that consumer-driven contracts require a site of responsibility or accountability. Mediated, brokered and routed messaging scenarios are perfectly amenable to consumer-driven contracts just so long as they don’t diminish service responsibility. It may be that I delegate some of my due diligence activities to a broker, which then matches my requirements against trusted providers; but even here, where I don’t know who exactly is satisfying my requests, I have a trust relationship, an expectation-obligation relationship, with at least one party – the broker – and therefore a potential site for consumer-driven contracts.

Theory into Practice

I ended my last post with the suggestion that in many cases it’s useful for a service provider to know something of its consumer-driven contract. Assuming you do want to know more about a provider’s current contractual obligations, we then need to ask: can you in fact discover what those obligations are? Can you identify a service’s consumers?

The answers to these questions will vary according to the environment in which a service provider is situated. In an enterprise environment, one in which the landscape is well known, it is often possible to identify all consumers of a service. Outside the enterprise, things may be more difficult. Services on the Web, for example, may have a largely anonymous clientele, making it near impossible to discover “existing” contractual obligations.

That’s not the end of the problem. Even if you can identify a consumer, it may still prove difficult to establish whether a relationship between that consumer and the provider is in fact currently in force. Whilst many such relationships are long-lived, particularly in the enterprise (I’m not talking about long-lived instances of a connection or transaction, merely the fact that for some period of time we can confidently say that service X is likely to collaborate or have some relation with service Y to satisfy such-and-such a business process), others are more ad hoc and less easily identified – a function of an agent crawling a service inventory, perhaps. In these circumstances, a snapshot of contractual obligations, even if some such thing could be generated, may well have some fuzzy edges.

The twin issues of the liveness and lifetimes of consumer-driven contracts and the consumer contracts from which they are derived are of renewed interest to me today. When does a consumer-driven contract begin? When does it end? When does it change?

I’ve no doubt that all three kinds of contract – provider, consumer and consumer-driven – are more or less in play in every distributed interaction, irrespective of the architectural and implementation decisions that have helped shape that interaction. But it’s clear to me now that the separation of concerns described in my original article was influenced heavily by the relatively static nature of the Web Services stack’s contract mechanism. WSDL is an upfront (partial) declaration of a provider contract. Clients activate an application protocol – engage in a conversation with a service – by invoking the operations that have been published in the WSDL (the protocol’s not inherent in the contract, only the levers by which it can be activated). By contrast, more RESTful services allow for a certain dynamism in the conversational aspects of a provider contract: representations in and of themselves advertise the levers by which a client can advance the application protocol, and they do this without reference to some pre-existing static contract map. Provider contracts in such services are “for the now,” and are exhausted in being consumed.

How do the forces at play in a RESTful interaction affect our understanding of consumer-driven contracts? If they make it more difficult to describe consumer relations outside of a specific instance of an interaction, do they not also make it correspondingly less important to know something of the consumer relation? My thinking is not settled on these issues. Sometimes I’m inclined to think of a consumer-driven contract as a resource, as a promise to provide such-and-such, to be provisioned by the provider for a certain period of time; at other times I prefer to see it as a function of per-request content negotiation. More on this another time.

Summary

In summary, Consumer-Driven Contracts describes in some detail the forces in play in any loosely coupled relationship. It does this by proposing that three types of contract exist between service providers and consumers. Real-world implementations of distributed systems exhibit all three types of contract, but the degree to which we can describe each contract, and the need to do so, varies according to the context.