Tuesday, August 5, 2008

Consumer Driven Contracts

A while back a reader sent me an email asking about consumer driven contracts and how they fit into my stance on SOA. I'd intended to share my thoughts on the approach with the rest of my readers but alas it slipped my mind. Better late than never though, so I thought I'd take the opportunity to discuss the concept now.

Consumer driven contracts as an approach is intended to provide inputs into the service provider's contract design to ensure relevance, as well as provide constraints on how a service provider's contract can evolve over time such that compatibility is maintained with consumers.

However the intention should always be that the service provider contract evolves in such a way as to better express the concepts of the provider. We don't want to reduce the semantic fidelity of communications with our services.

I would say that as long as you're sticking mainly to publish-subscribe messaging (that is, avoiding command messages), then the needs of the consumer are considerably less relevant. Consumers are only informed of events as they happen. Command messages produce a subtle form of coupling where the service consumer instructs the service provider what to do.

Services that publish events do not prescribe or assume what subscribed services will do (if anything) once a notification message is received. An event message describes only an event that occurred within a service. The subscribers should really have no influence on this. As such, they should not be influencing the schema of the event messages published by the service provider.

So when using publish-subscribe messaging, I would suggest that consumer contracts are useful only in providing constraints on what can be changed in the service provider's contract in order to maintain compatibility with its consumers.

That being said, service contracts tend to be quite stable with process-centric self-contained service models - so I've not personally found consumer driven contracts worth the effort.

Consumer driven contracts really come into their own with data-centric contracts and centralised data architectures. When we always need to go and get our data from elsewhere, and all our service consumers use that data for different purposes, consumers have a substantial dependency on the service provider's schema. They will likely need to influence the provider's schema quite regularly. That in turn will affect the other consumers.

This is yet another reason to pursue process-centric service contracts with decentralised data architectures. It keeps your service contracts stable by virtue of minimising dependencies between service providers and consumers. You can read more about service contract stability here.

2 comments:

iansrobinson said...

Hi Bill

Some really excellent points here. I agree that consumer expectations of a data-centric service can vary wildly from consumer to consumer; whereas business-meaningful capabilities hosted in business services aligned along organizational lines tend to be consumed in a more homogeneous fashion. Understanding this difference helps determine when to push for full-blown consumer-driven contracts, and when to downplay their significance.

Having said that, my thinking around consumer-driven contracts has evolved in tandem with my preference for hosting business capabilities in services aligned around organizational units and business-meaningful processes, and for using publish-subscribe, event-driven interactions. Go figure!

Business services often end up being threaded in several different enterprise processes, with slightly different usage patterns and consumer expectations, and to that extent consumer-driven contracts help describe the aggregate usage context on behalf of a provider. To a degree, consumer contracts serve as an antidote to enterprise canonical schemas: product, for example, has different semantics in different, yet specific usage contexts. The only things of real importance are these specific instances of usage, which show what really needs to be provided, in this context or that, in order to realize this outcome or that, rather than some perfectly normalized Platonic schema.

With regard to events and notifications, I’ve used a very lightweight consumer-driven approach, in the form of “stories for services,” to help discover which events a service ought to publish: if nobody’s interested, don’t waste your time publishing to the void.

Anyway, great blog – I only came across it today after going over some of Udi’s old posts. Glad I’ve found it.

All the best

ian

Bill said...

Hi Ian,

Thanks for your comments. Indeed business services will participate in several different enterprise processes.

The granularity of your business services will however determine the number of complexity of business processes in which each business service participates.

If business services are very coarse grained, aligning with high level business functions (cohesive process areas), then each business service will participate in comparatively fewer business processes. These business processes will be very high level broadly scoped (end-to-end) processes.

If business services are very fine grained, then each service will participate in orders of magnitude more business processes, the needs of which will all need to be accounted for and managed.

To that end, I would suggest that consumer driven contracts are of limited use if the business service granularity is appropriate.

To use your product example, a product should have single representation within a given business service, but different structure and semantics across different services.

The publishing service expresses its events with the structure and semantics appropriate for itself. Other services then map this representation to their own representations when notification messages are received.

With regards to deciding which events to publish, I tend to publish all relevant business events, regardless of whether there are any existing interested subscribers.

With SOA, the ideal unit of reuse is the event rather than the function (which you can read more about here).

If you aren't publishing all business relevant events, then when it comes time to implement a new business process within a service component one would need to go back to the service where the event occurs and modify it in order to publish the event.

The business architecture should determine which events will be published. Business events are used within the business architecture description to coordinate the execution of business processes (see Event Driven Process Chains).

Cheers,
Bill