Applied SOA: Part 4 – Service Taxonomy

This is part of a series of blog post about Applied SOA. The past blog entries are:

In this article, I’ll cover the Service Taxonomy.  On an SOA project, we’re going to have services.  How should we classify them?

First why would we want to categorise them?

First, to give a structure to the solution.  Without structure, it’s hard to govern an important number of elements, especially if those elements are services.

Second, at the architecture level, we can give rules for categories as opposed to individual services.  Again, this is structure, we can manage fewer pieces.

Third, at the design level the taxonomy will help us clarifying the boundaries of a service.  At the end of the day, there are two extremes:  either you have one service with all the operation of your company in it or a lot of services with one operation each.  A service is just a container and unless you have some clear taxonomy, which operation belongs to which service can be a matter of taste and individual preferences, which seldom yields strong design decisions.

Finally, it gives us the ability to reason about the structure at a higher level without getting cut in the intricacy of specific services.

There are many ways to categorise services.  A popular one was defined by Tomas Erl in his book SOA Design Patterns.  That taxonomy is based on a few patterns exposed in that book.  Each pattern invokes separation of concerns in order to define a service layer.  Two axis are used for the separation of concern:

A component is said to be agnostic to the business context if it can be invoked from any business process and behave identically.  A component is said to be business logic specific if it contains business logic.

Nevertheless, this taxonomy is useful.  It defines three layers:

Reusability is maximal at the Utility Layer and minimal at the Task Layer.  At the Task Layer, a service is specific to a business process (context) and can’t be reused elsewhere.

Business Logic increases as we go to the Task Layer.

Composition is done for the Task Layer to the Entity and to the Utility layer.  By composition I mean that a service from one layer can call a service from another one.  This is probably the strongest property of this taxonomy:  the composition rule is deduced from the definition of the taxonomy as opposed to imposed as another principle.

For example, a service at the Entity Layer, by definition, can be called from any business process.  It cannot, therefore, call a service at the Task Layer, being specific to only one business process.

I’ve used this taxonomy in the architecture of a sizable SOA project.  It worked well in terms of given structure and was quite resilient to changes along the project (e.g. security requirements, multiple consumers, etc.).

Something we did to enrich the taxonomy was to further subdivide each layer per domain.  A domain being an information / process breakdown.  Given those subdivisions, each service could only be within one layer and serving one domain within that layer.  That gave a very strong & clear service boundary definition.

Now the weakness of the taxonomy, we’ve found, is the vagueness of the definition of agnosticism to business context & business logic.  It sounds great on paper, but my service designer team, composed of brilliant and seasoned designers, spent the project having philosophical discussions about what is and what isn’t business context agnostic.  It boiled down to the fact that an operation being or not aware of the business context isn’t always clear.

On smaller project I’ve seen a taxonomy based only on data domains, hence having only an entity layer.  This simplifies the clustering of services as data domains are typically quite clear.  It does mix the concerns of process centric & data centric capabilities though.

One response

  1. cavada1 2012-03-26 at 05:54

    Just a quick question about how you define a task service in this taxonomy, as I’m having similar debates about what constitutes a task. Could a task service be a small “action”, ie an operation that doesn’t require composition? So if I have a requirement to allow customers to update their personal info, like address, would I have a task service named ChangeCustomerMailingAddress, that in turn calls the update operation on the Customer entity? Or would it be better to call the entity service directly? Another example would be retrieving data, like RetrieveCustomerBillingHistory, would that be a separate task service, or just an operation on the Customer entity service?

    Any insight is appreciated. Thanks

Leave a comment