Sound advice - blog

Tales from the homeworld

My current feeds

Fri, 2010-Aug-13

REST-compliant service contract notation

and are traditional rivals for developer mindshare. Despite this I think they have a lot in common, and in my view a fair amount that each opposing camp can teach the other. I have been looking forward to the convergence between these camps and their styles for some time now, and I have been working on a title called SOA with REST with several other authors that explores this intersection. My understanding of the intersection of REST and SOA has evolved and expanded over this time to a point where I comfortably use some of the techniques of service-orientation to build and define REST architecture. So much so, that the line between what is REST practice and what techniques are from service-orientation have somewhat blurred.

Today I wanted to take the gentle reader through a few basic concepts of the uniform contract: How to define and build services that are compliant with the REST uniform interface constraint, but are able to express their unique service capabilities. I have approached this subject from a few different directions in the past, but this time around I particularly wanted to cover what it means to talk about service contracts within the context of the REST uniform interface constraint.

From a SOA perspective, compliance with the uniform interface constraint requires that across our service inventory (or a significant proportion thereof) we are able to define a single technical contract that can be used to access any resource. This constraint increases integration maturity of a service inventory by allowing one resource to be substituted for another by service consumers at runtime as required. It allows service consumers to discover a resource at runtime that they wish to interact with, and to interact with it correctly without changing any of its logic and without introducing any kind of glue logic. At the same time it replaces the conventional single "service endpoint" with often infinite sets of resources that each form a lightweight endpoint for the service.

The uniform interface constraint simplifies the architecture by reusing very general contract elements that services, consumers, and middleware can all understand and participate in effectively. This initially reduces performance, but leads to improvements in scalability and other architectural properties by allowing middleware such as proxies to be involved in scrutinising and supporting network interactions. It can massively reduce coupling within a service inventory and allows for extremely simple dynamic reconfiguration of service compositions.

I see part of the friction between the two camps as coming down to a lack of shared terminology when talking about services, contracts, and interfaces. I would like to see if I can clear this up a little with a few diagrams:

Uniform and Service Contracts

This first diagram shows the key elements of the uniform contract, and the relationship between a uniform contract and a service contract. There are a number of key points to draw from it.

REST advocates will have immediately picked up the obvious extension of a conventional uniform contract with the service contract concept. This is a startling inclusion and one that deserves explanation. Let me begin this explanation with another diagram:

REST-compliant service contract realisation

This diagram shows a simple REST-compliant realisation of an abstract service. The high level capabilities that analysis suggested this service needs were the capability to convert from degrees Fahrenheit to degrees Celsius, and the corresponding capability to convert back again. These capabilities were refined through reference to the uniform contract into a service contract suitable for use in a REST-style SOA. The name of the service is the same as the authority of the service's resources ( to ensure maximum autonomy of this service. Resources in the contract are identified relative to the identifier for the service.

The actual contract definition can be written in many different ways, but I find this one is easy to use to communicate with people from either an object-oriented or a service-oriented background. What this notation does is to provide a clear service boundary for the REST-compliant service, a clear identification of the service capabilities (which remain readable), and a clear relationship to facets of the uniform contract.

The service capabilities in this case have been refined as:

It is clear from a REST perspective that what we are doing is specifying the resource identifiers that the refined service provides to its consumers. It is normal to expect that a REST-compliant service will define its own resource identifiers to use in conjunction with the uniform contract facets. These resource identifiers provide business context for generic and abstract methods such as "GET".

In the example above we are promising to support a GET operation to two distinct families of resource identifiers. One set will return the number of degrees Celsius for a Fahrenheit value, and the other set will do the reverse. Both will return their result as a simple text-formatted number. Each different value that can be input to the service is embodied in a different identifier, so each refined capability is actually defining a family of resources.


Services and consumers are more loosely coupled with each other in a REST-style SOA than in a conventional SOA. While SOA always encourages the use of loosely-coupled contracts to support implementation changes behind the contract, REST encourages us to abstract the consumer away from design-time knowledge of the service contract itself. Service consumers and middleware are coupled to the uniform contract, and are sufficiently abstracted from specific service contract details to be reusable from service to service.

With this objective in mind, I think it is useful to talk explicitly about service contracts as an element of REST. We need to talk about them because they are important in governing, developing, maintaining, and supporting REST-compliant services. We need to talk about them so that we can offer explicit guidance about what constitutes coupling of a consumer to a service contract. We need to talk about them so that we can point to patterns that help build the loosely-coupled architectures that REST demands.

If we are able to explicitly talk about service contracts, we will be in a better position to understand how they shape our service inventories and our architectures.