Architecting with Services

As I alluded to in a previous post, I have been thinking about the architecture of services for the past couple of weeks.  This is quite different (at least as I see it) from the many descriptions of how to implement web services.  Because I'm relatively known for Web services in the user group community here in Toronto, I get asked things like “Where do my service boundaries begin and end?” and “What parameters need to be passed into a service?”.  While it is easy (and sometimes even fun) to be flip with my comments regarding, my annoying streak of professionalism means that occasionally I have to consider the ramifications of my answers.

Naturally, the basis for the answer should come from some sound theory.  For service orientation, there is little more sound than the Four Basic Tenets of Service Orientation first espoused by Don Box.  In summary, they are:

1.  Service boundaries are explicit and costly to traverse

2.  Services are autonomous

3.  Services expose schema and contract, not class and type

4.  Services negotiate using policy

While is there an on-going discussion about the completeness of these tenets, they are certainly a good starting point for this post.  In particular, I've been trying to decide if all of these tenets apply equally to the design process.  My conclusion is that they don't. Let's start with the first one: Service Boundaries are Explicit and Costly

This is a double-edged sword, from a design perspective.  First, I believe it is important to consider the possibility that the cost to traverse a boundary is high. This is a necessary (and frequently lacking) mind set to adopt when creating and using web services.  I don't believe that it should be any different with the design of the web service. 

On the other hand, if the high cost for boundary traversal is always the assumption, the design decisions may not result in the most efficient application.  In particular, consider the need for a service that provides information about a business entity, such as a customer. The kind of service I'm thinking about is one that implements basic CRUD functionality.  Now if the assumption is made that boundary traversals are costly, the exposed interface will be such that all possible information about the business entity will be passed to the service for every method.  This would reduce the chatty nature of the typical CRUD methods. 

However having a chunky CRUD service is not necessarily the most efficient use of resources.  Why pass all possible information when only a little might be sufficient.  Especially when, as would be the case in most CRUD services, the service is more likely to be a near link than a far link.  All of this leads to my slight variation on the Tenet:

Service Granularity is Proportional to Expected Latency

When designing a service-oriented application, it is certain necessary to consider the cost involved in calling across the various service boundaries.  However, it is also necessary to consider the expected latency.  In this way, the appropriate design decisions regarding the number and content of the exposed messages can be made with an eye to both flexibility and performance.

I've got some thoughts about the other tenets as they apply to design, but they will have to wait for another blog entry.  And if anyone has thoughts about my logic, I'd be happy to hear about it.