Contract
Denormalization
How can an agnostic service contract be designed to
facilitate a range of consumer programs?
|
Problem
Agnostic services with
normalized contracts can impose functional and performance constraints on
some consumer programs.
|
|
Solution
Service contracts can
include a measured extent of denormalization, allowing multiple capabilities
to redundantly express core functions in different ways for different types
of consumer programs.
|
|
Application
The service contract is
carefully extended with additional capabilities that provide functional
variations of a primary capability.
|
Impacts
Overuse of this pattern on
the same contract can dramatically increase its size, making it difficult to
interpret and unwieldy to govern.
|
|
Principles
Standardized Service Contract,
Service Loose Coupling
|
Architecture
Service
|
Table 8.3 – Profile summary for the Contract
Denormalization pattern.
Problem
Because agnostic services can be utilized within a variety
of compositions, it is difficult to express each capability in such a way that
it is suited for each possible consumer program.
For example, a capability may not return a sufficient amount
of data in response to a consumer request or, more commonly, it provides too
much data thereby imposing transmission and processing overhead upon the
consumer program (Figure 8.x).

Figure 8.8 – The Invoice service provides a Get
capability that is not be able to facilitate the varying granularity levels
different service consumer programs want.
Solution
Unlike pursuing normalization across a service inventory (as
per the Service Normalization pattern) where denormalization can impact
autonomy and governance of individual services, the level of acceptable
normalization across a service contract is more flexible.
This flexibility allows for increased contract design
options, including strategic incorporation of the denormalization of expressed
functionality. In other words, the processing of one service capability does
not need to be limited to one capability. Capabilities with redundant functionality
offered at different levels of granularity can be provided to support multiple
consumer and composition requirements Figure 8.x).

Figure 8.9 – Equipped with additional (albeit
redundant) capabilities, the Invoice service is able to better accommodate the
individual requirements of the three consumers.
Application
Depending on the nature of the capability logic, there are
some common ways that this pattern is applied:
• The
same capability can be offered at different levels of granularity. As already
illustrated in Figure 8.x, an entity service can contain different Get-related
capabilities that can get entire document, get just the document header, or get
one or more document detail items (or a specific document property).
The latter two types introduce
functionality that overlaps with the first, and are therefore redundant.
However, by providing this targeted set of denormalized capabilities, a range
of consumer program requirements can be more effectively addressed.
• Another
example is a capability that is added to an existing task service. Even though
the task service encapsulates a body of business process logic, one or more capabilities
can be added to expose segments of the process logic (normally in the form of
modest sub-processes). This can establish alternate entry points into business
process logic, but from an endpoint perspective, the capabilities appear to
encapsulate redundant logic.
Even though this pattern intentionally introduces functional
redundancy into the contract, there is typically no need to add significant
functional processing to the underlying service logic. If all related
capability definitions can be processed by the same set of components, the
corresponding routines can be parameterized and shared.
Impacts
Overuse of this pattern can lead to overly large and
convoluted service contracts. If multiple variations of each primary capability
are added, the contract can become unmanageable and difficult to evolve. The
effectiveness of agnostic services especially can suffer from poor functional
expression.
Furthermore, adding capability variations that expose
redundant functionality may require the creation of multiple, also redundant
schema definitions. A Web service implementation, for example, could easily be
comprised of numerous schema files, making its governance increasingly
challenging.
Relationships
Contract Denormalization introduces additional capabilities
into a contract, most of which will repeat the expression of functionality.
This is why the Service FaŤade is commonly applied in support of this pattern;
it allows for a single faŤade component to interact with other components and
routines on the service back-end in order to facilitate redundant contract
capabilities without the need for redundant service logic.
The flexibility to apply this pattern is further increased
via the Decoupled Contract pattern, primarily because it provides the freedom
to fully customize a service contract independently for its underlying
implementation.
Service Normalization does not directly relate to Contract Denormalization,
but it is interesting to note that despite its name, this pattern does not
interfere with the pursuit of normalizing service boundaries. The boundaries
remain the same, only the contract content changes.

Figure 8.10 – The Contract Denormalization pattern
allows for the extension of contracts with redundant capabilities and therefore
relates mostly to patterns that can support this requirement.
Case Study Example
Case study content is not available on this Web site.