The ProductSearch service is currently consumed by two applications: an internal marketing application and an external reseller’s web application. Both consumers use XSD validation to validate received documents prior to processing them. The internal application uses the CatalogueID, Name, Price and Manufacturer fields; the external application the CatalogueID, Name and Price fields. Neither uses the InStock field: though considered for the marketing application, it was dropped early in the development lifecycle.
One of the most common ways in which we might evolve a service is to add an additional field to a document on behalf of one or more consumers. Depending on how the provider and consumers have been implemented, even a simple change like this can have costly implications for the business and its partners.
In our example, after the ProductSearch service has been in production for some time, a second reseller considers using it, but asks that a Description field be added to each product. Because of the way the consumers have been built, the change has significant and costly implications both for the provider and the existing consumers, the cost to each varying based on how we implement the change.
There are at least two ways in which we can distribute the cost of change between the members of the service community. First, we could modify our original schema and require each consumer to update its copy of the schema in order correctly to validate search results; the cost of changing the system is here distributed between the provider – who, faced with a change request like this, will always have to make some kind of change – and the consumers, who have no interest in the updated functionality. Alternatively, we could choose to add a second operation and schema to the service provider on behalf of the new consumer and maintain the original operation and schema on behalf of the existing consumers. The cost of change is now constrained to the provider, but at the expense of making the service more complex and more costly to maintain.
Interlude: burdened with services
Chief among the benefits of service-enabling an enterprise’s application landscape are increased organisational agility and reduced overall cost of implementing change. An SOA increases organisational agility by placing high-value business functions in discrete, reusable services and then connecting and orchestrating these services to satisfy core business processes. It reduces the cost of change by reducing the dependencies between services, allowing them to be rapidly recomposed and tuned in response to change or unplanned events.
A business can only fully realise these benefits, however, if its SOA enables services to evolve independently of one another. To increase service independence, we build services that share contracts, not types. Even so, we often end up having to evolve consumers at the same rate as the service provider, chiefly because we’ve made the consumers depend on a particular version of the provider’s contract.
In the end, service providers find themselves adopting a cautious approach to changing any element of the contract they offer their consumers; this, in part, because they cannot anticipate or gain insight into the ways in which consumers realise this contract. At worst, service consumers ‘realise’ a provider contract and couple themselves to the provider by naively expressing the whole of a document schema within their internal logic.
Contracts enable service independence; paradoxically, they can also couple service providers and consumers in undesirable ways. Without introspecting the function and role of the contracts we implement in our SOA, we subject our services to a form of “hidden” coupling that we are rarely equipped to address in any systematic fashion. The absence of any programmatic insights into the ways in which a community of services has adopted a contract and the lack of constraints on the implementation choices made by service providers and consumers, combine to undermine the purported benefits of SOA-enabling the enterprise. In short, the enterprise becomes burdened with services.