Service Oriented Architectures are built upon four tenets:
- Service boundaries are explicit
- Services are autonomous
- Services share contracts not code
- Services are compatible based on policy
When building services, it’s important to remember that these are tenets, not laws. This is important because service-oriented systems are built differently depending on their size. Michele Leroux Bustamante underscored this distinction earlier this week at Dev Connections by using the terminology “big SOA” and “little SOA”. When building little SOAs, it is difficult and some times impractical to adhere to the above guidelines. For example, in the figure below, service one and two are crossing the boundaries by accessing the same data store. While this may clash with the first SOA tenant, that’s OK.
In the case of little SOA, dogmatic conformance to the tenets could incur performance, maintenance, and other such cost that will inhibit its success. Big SOA is the orchestration and composition of multiple little SOAs. If unquestioned devotion to the tenets of SOA impede the construction of the little SOA building blocks, there can be no enterprise-level service-based architecture.
The construction of these different sized services vary in other ways as well. For example, a big SOA is often built from many smaller, entity services. An entity service is one that provides basic CRUD for database entities. These services often provide dozens of different operations to perform this type of basic functionality; however, they aren’t limit to simple CRUD functionality and commonly include other operations that are still relatively low-level. For example, one may create an asset service which exposes basic asset-related CRUD functionality in addition to other capabilities such as grouping and relating assets. Regardless, all of these operations end up altering database records.
When building this type of service compared to one that makes up part of a big SOA, it is impractical and unnecessary to adopt the recommended practice of explicitly defining the message contracts of the entity services. If this guideline is adapted, the entity service will require two message contracts for each operation, resulting in an overwhelming number. Furthermore, these messages of such services often contain nothing more than a data contract, resulting in a senseless wrapper. Though Juval Löwy advices in his book Programming WCF Services that service contracts should expose only a handful of operations (with a suggested upper limit of 20), little SOA building blocks like entity services usually can’t follow this recommendation.
On the other hand, when building the services of a big SOA that cross organizational boundaries, small, specialized, highly-interoperable services are paramount. To achieve this, the definition of message contracts is a must. Unlike little entity services, however, these wide-reaching services often expose very few operations and only a handful of message contracts. This is very manageable and merits the cost of defining, versioning, and maintaining the extra message-level contracts.
The point is this: architects can’t be unquestionably apply the tenets of SOA in a back-or-which fashion. We have to open-mindedly question and think critically about our problems and the established service-oriented guidelines for building loosely coupled architectures.