The document discusses guidelines for versioning service contracts to enable reuse and compatibility between different versions of services and consumers. It argues that a versioning strategy is essential to achieve reuse and realize the business benefits of SOA. The key elements are:
1) Define machine-readable contract elements in WSDL that specify validation rules at runtime.
2) Establish compatibility rules between contract versions to determine if new versions are backwards/forwards compatible. Non-breaking changes result in minor versions while breaking changes require major versions.
3) Design message type schemas for extensibility using XML features like <xs:any> to enable forwards compatibility and allow unknown future extensions. Consumers must accept and ignore unknown elements.
1 of 20
More Related Content
Contract Versioning
1. Contract Versioning, Compatibility and
Composability
Kjell-Sverre Jerijærvi, Jean-Jacques Dubray
In the recent weeks, many industry analysts have been prompt to point out fears, uncertainties and
doubts about SOA. Gartner, for instance, claims that companies with plans to start SOA initiatives are
falling, while companies which plan no SOA initiatives have increased from 6 to 16% in the last 12
months. These notes and articles often sound as if companies no longer believe in building reusable IT
assets which can be composed in different solutions.
We believe that the explanation for this lower level of interest in SOA is quite different: one of the key
failure of SOA initiatives has been precisely the inability to produce reusable and composable assets. It
seems as if that every new consumer brings enough fresh requirements to mandate a service different
from existing services. Since services are more expensive to design, build and operate when compared
to more traditional solution architectures, SOA cannot realize a large part of its business case when
these services can’t be reused. To our experience, few companies have been able to move beyond
primitive reuse of services to achieve the promised effects of SOA.
If you ever hope to reuse a service, it is imperative to have clear design guidelines for contracts that
express what this service provides and how it can be consumed. You may be able start your SOA
initiative without much SOA Governance, but it would be a mistake not to have contract design
guidelines. Overtime, these design guidelines will of course become a central part of your SOA
Governance design compliance policies. It seems, however, that the industry as a whole has put a heavy
emphasis on SOA Governance processes as a way to successfully build reusable assets, often dismissing
the “Just a Bunch of Web Services” (JaBoWS) approach, but this strategy has yet to prove that it is
enough to accomplish this particular goal.
We argue that SOA Governance is necessary but cannot generally deliver Service Specifications that are
at the level required for reusing assets over long periods of time. SOA Governance is important, and as
much governance as practical should be practiced when identifying, specifying and designing a service.
However, because of limited resources, time and the inability to predict the future well beyond a 3-6
month horizon, Governance alone cannot create reusable assets. Inevitably, new and unforeseen service
consumers will come with new requirements that will require an evolution of existing services. Without
a proper versioning strategy, new versions of a service will result in a new service altogether, creating
the need for similar, yet separate registry entries, code bases and lifecycles. Organizations without a
proper versioning strategy often deploy, operate and maintain several “versions” of the same service in
1
2. production drastically limiting SOA’s benefits and Return-On-Investment fueling comments from some
analysts who have been prompt to claim that “reuse” should not be expected as part of a SOA initiative.
In this article, we provide a series of recommended practices for establishing a Service Contract
Versioning strategy geared towards service reuse, composability and compatibility with prior consumers
(or providers). We claim that such versioning strategy is essential to achieve satisfactory levels of service
reuse and in turn generate higher (and expected) ROI from SOA initiatives.
Elements of a contract
“A contract is the most important metadata in SOA”, says Ron Schmelzer, analyst at ZapThink. There are
many parts to a contract between a service provider and a service consumer. Some of these elements
can be made machine readable, and even for some enforceable at runtime, using technologies such as
XML Schema, WSDL and WS-Policy specifications for instance, while other elements will remain mostly
for human consumption only.
The goal of this paper is not necessarily to look at every possible elements of a contract from the format
and sequence of the bits that travel on the wire, to service level agreements or legal statements (about
privacy for instance). Rather, we would like to focus on one simple problem: defining a strategy that
supports the evolution of a service provider or consumer while remaining compatible with existing
consumers or provider, respectively. We believe that this strategy is core to delivering the benefits of
SOA and can greatly reduce both the initial cost of building a service (because it reduces the need for
governance) as well as the ongoing service maintenance and operations costs.
The proposed versioning strategy is twofold:
a) Create machine readable contract elements that express all rules enforced at run-time by both
the service consumer and provider
b) Create or leverage a set of compatibility rules between the versions of the contract elements
agreed upon service consumers and providers
Machine readable contract elements are the foundation of versioning because this metadata can and
must be used by both the service consumer and provider to decide whether the current message sent to
and received at an endpoint will and can legitimately be processed. These elements define the lowest
bar for a potentially successful processing of a given message. Of course, business rules in the service
implementation can potentially return a contract exception.
One strategy could be to define no machine readable contract element and keep exchanging exceptions
each time the consumer or provider cannot process a message, until either the consumer or the
provider fixes the problem. For instance, members of the REST community have advocated the adoption
of a “uniform contract” dismissing the need for further machine readable elements which could have
otherwise provided unambiguous semantics while assisting in the implementation, validation or
configuration of a service. Yet, the REST community does not provide evidence that RESTful Web
Services can be evolved in a compatible way.
2
3. The problem is less about which contract elements one needs, but how to facilitate the expression of
compatibility between two versions of a service provider (or consumer). In other words if a consumer
interacts with a new version of service provider, are we expecting a behavior equivalent to the prior
version or not? Adopting a “uniform contract” such as agreeing simply on sending and receiving
messages at a particular location is not going to help answer the compatibility question.
In this article we will focus on the metadata necessary to validate whether an incoming SOAP message is
legitimate or not. So we will focus on the contract elements defined in a WSDL document. Since the
usage of WSDL 2.0 is not yet widespread, we will be using WSDL 1.1. We do not believe that there would
be any significant changes when applying this strategy to WSDL 2.0. The elements of WSDL 1.1 include:
Service definition target namespace
Message types
Message definitions
Port types
Bindings
Service definitions
Optional policies expressed using WS-Policies
Fig 1. Elements of a WSDL 1.1. Contract
Versioning guidelines
Service and Schema Versioning can lead to these types of compatibility scenarios (Fig 2):
No compatibility
Forwards Compatible
Backwards Compatible
3
4. A new version of a contract that continues to support consumers designed to work with the old version
of the contract is considered to be Backwards Compatible.
A contract that is designed to support unknown future consumers is considered to be Forwards
Compatible. Such a contract anticipates that consumers will evolve over time by supporting extensibility
through XML Schema wildcards. This type of compatibility is often found in B2B scenarios where a
consumer works with multiple service providers which may evolve at a slower pace. In the enterprise,
the most common scenario is backwards compatibility.
Backwards compatibility is what is typically meant by “compatible” and is possible when non-breaking
changes are made to a contract. Making breaking changes to a contract will always lead to no
compatibility. These scenarios have been extensively described in the literature by John Evdemon or
Dave Orchard for instance.
Note that contracts can be both backwards and forwards compatible (more on this later).
Fig 2. Service Operations Compatibility Scenarios
The degree of support of Web Services technologies for both forwards and backwards scenarios is
unmatched in the distributed computing technologies world. Neither RPC, CORBA, DCOM or JEE have
been able to support these scenarios out of the box, simply by applying specific design constrains. As a
matter of fact the ability to support these scenarios is a key to achieving loose-coupling and reuse.
When a service is evolved in a backwards compatible manner, it can be reused by more consumers,
without requiring existing consumers’ implementation or configuration to change. When Governance
has failed to predict the needs of future consumers or when the budget prevented to get all the features
needed in V+0, compatible service versioning is what enables updates without impacting existing
consumers’ operations. In particular, this is how “JaBoWS” can slowly but surely evolve into Enterprise
Class services, serving a wide range of consumers.
4
5. Compatibility is defined by a stated versioning scheme:
Major versions: incompatible (breaking change)
Minor versions: compatible (non-breaking change)
Breaking changes are modifications, for instance, to existing schema types that will cause processing of
incoming messages to fail, such as changing an existing optional element to be mandatory or adding
new required elements. Non-breaking changes are e.g. adding a new optional element. Non-breaking
changes to schemas or services are registered as minor versions, while breaking will always be
registered as a new major version.
All the versionable artifacts of a service will be affected by changes, and these changes will ripple
through the artifacts from bottom to top, and eventually the ripple effect will impact your consumers.
This ripple effect is detailed in table 1 and illustrated in figure 3. While versioning lets you control the
effects of changes, compatibility helps you alleviate some of the negative effects of versioning.
Fig 3. The ripple effect of changes
In the following, we will state that a service version is incompatible using a major version and a
compatible version (forwards or backwards) using a minor version. Point version should be used to
denote versions that did not involve contract changes and were limited to implementation, deployment
or configuration changes (for instance a bug correction, a new service container release, etc). Point
versions are always compatible by definition (again this is a statement not a guaranty).
Artifact Change Major Minor Point
Service Breaking X
Service Non-Breaking X
5
6. Composite Service Incompatible Schema Service X
Composite Service Compatible Service X
Service Incompatible Schema X
Service Compatible Schema X
Schema Breaking X
Schema Non-breaking X
Schema Aggregate Incompatible Schema X
Schema Aggregate Compatible Schema X
Code Bug fix / maintenance X
Code Safe modifications X
Code Semantic / Unsafe modifications X
Other service Any X
artifacts
Table 1. The versioning ripple effect of changes to code, schemas and services
Two message types can be stated to be compatible using these simple rules when designing Message
Type Schemas:
XML Namespace values must be constant for a given message type and a given major version
Message type schemas must include mandatory minor and point version custom attribute on
the message type root element, using for instance a type xsd:int.
Whether XML validation is used or not, each message consumer must verify that the major
version of an incoming message is matching its own implementation version. An exception
should be returned when the major versions of the message sender and receiver do not match.
In the .Net world, Message Type artifacts are also known as data contracts.
6
7. Web Services Extensibility Guidelines
The principles of forwards compatibility have been well documented (see also this reference), yet they
are rarely applied. For the sake of clarity we are detailing them here.
Service definition target WSDL target namespace can be different from Message types XML
namespace Schema namespaces. WSDL target namespace must be different each
time the service contract or implementation is modified, be it for a
point, minor or major version
This namespace is not used at runtime, provided that SOAP actions are
defined manually instead of automatically by the runtime. Therefore, all
WSDL definitions MUST include manually defined SOAP actions1
Message types Message type schemas must be designed with the utilization of XML
Schema extensibility mechanisms (we provide a detailed discussion of
these mechanisms below)
Message type namespaces must only refer to a major version of the
service contract, indicating an incompatible service version. Minor
version may be specified as an attribute to the root element
Message definitions Parts can potentially be added to message definitions, we however
recommend to use a single part which contains a message envelope in
which content can be extended using XML Schema’s extensibility rules
Port types Port types can be extended with new operations
No changes can be made to the operation’s signature nor the order in
which the operations are called (which is not specified in WSDL)
Bindings New bindings can be defined, however, existing bindings cannot be
modified, including the endpoint of the service
Service definitions Services definitions can only be extended with new ports, existing ports
cannot be altered
Optional policies expressed There are no general framework available to assess compatibility
using WS-Policies scenarios for policies
Table 2. Service Definition Compatibility Design Rules
The design of Message Types using XML Schema must be carefully planned to achieve forwards
compatibility, also known as XSD extensibility.
John Evdemon explains:
The XML Schema standard introduces <xsd:any> as a wildcarding element.
<xsd:any> enables schemas to be extended in a well-defined manner. <xsd:any>
includes a namespace attribute that either constrains or extends the range of
elements that might appear within the wildcard. The namespace attribute can be
set to any of the following:
##any enables the use of elements from any Namespace to extend the schema.
##targetnamespace restricts wildcards to the elements that appear within the
targetNamespace.
7
8. ##other makes it illegal to extend the schema using elements from the
targetNamespace.
The processContents attribute dictates how schema extensions should be
validated by the parser:
strict requires the parser to validate all schema extensions.
skip turns off validation for schema extensions.
lax validates elements from supported namespaces and ignores unknown or
unexpected elements (most Web services specifications use lax).
Regarding XSD extensibility, there is a snag in the XML Schema’s 1.0 specification. Because of the
unique particle attribution (UPA) rule there is an ambiguity during the validation of XML Schema types
that have an optional or unbounded number of elements as their last element in the type definition. For
that reason, when the last element of the type has a variable cardinality, we have to add a specific
element with a cardinality of exactly one, before using the <xs:any
namespace=“##targetNamespace”…/> element.
For instance, you may want to choose an element such as this one:
<eovMxmy> where x and y are the major, minor version numbers (eov stands for end-of-version)
In XML Schema 1.1 this ambiguity will be removed and this additional element will not be needed.
Using XML Schema extensibility features is one thing, but we still need to define and agree on a set of
rules when an older version of a message consumer encounters a new version of a message. It is likely
that this new message will have elements that fall in the some of the extensibility sections. The question
becomes then, what should we do with these elements? We recommend applying the following rules
which result in Forwards Compatibility requiring no consumer side changes:
The behavior of a service when it encounters an unknown element must be clearly defined by
an extensibility handling rule as part of the contract
New elements added to a new version of a message type designed to be forwards compatible
must not invalidate the prior version of the message type
Consumers of a message must accept and remove from processing any element that they do not
recognize
Responses generated from a request that contains the same types as their corresponding
request must add the corresponding elements they removed prior to processing the request
8
9. These rules ensure that every consumer is in the position to use XML schema validation for the elements
that it is bound to process in its implementation. In no way, we are recommending to use of XML and
XML schema extensibility in a sloppy and forego validation (Figure 4). Contrary to a widespread belief in
the industry, XML and XML Schema extensibility is essential to a compatibility-based versioning
strategy, and hence essential to achieve reuse.
Consumers and providers’ implementations are asymmetric when it comes to their implementations:
If the consumer validates the incoming messages sent by the provider, they will pass validation
(because of the implementation rules defined)
However, -and of course- the service provider implementation must in general keep track of the
schemas for all the minor versions for incoming messages and validate each incoming message
based on its minor version number for a given major version, even possibly route the call to
variants of the implementation
The reason for that is because an upper minor version schema cannot validate a lower version schema
(in general). The upper minor version will most likely have required elements in the same target
namespace that cannot be validated with a lower minor version schema.
Consumer Variations
There is also a need for “extension areas” in an XML Schema that are different from versioning (Figure
4). For instance, extensions are common when consumer specific variations are needed, i.e. when
specialized relationships between consumers and providers (independently of other consumers) are
necessary. These extensions can be viewed as a private contract between a particular consumer and the
service provider, embedded in the contract common to all consumers. Again, having a strategy to enable
these extensions is essential to achieve a good level of reuse of services.
Extensions must be treated separately from the general versioning patterns. We recommend
implementing extensions using a single element under the root element of the message type.
Extensions must not be processed by the message consumer, unless they are explicitly defined
in its message type or unless specified with a mustUnderstand=’true’ attribute. The message
consumer’s implementation must generate an exception when it cannot process the required
elements.
It is advised to have extensions belong to a different namespace from the root of the message
type.
9
10. Fig 4. Versioning and User Extension Compatibility
With Web Services technologies, the fact that one may use different endpoints to access the same
information via different versions of the business logic simplifies greatly the maintenance and
operations of the corresponding services. Overall, Web Services technologies, XML and XML Schema
offer unprecedented opportunities to support compatibility scenarios unlike distributed computing
technologies before them, including REST which cannot rely on a stable contract to specify a versioning
strategy. In REST, the fact that each resource exposes an endpoint is creating a strong coupling between
the endpoint and the resource and makes it difficult to operationally manage multiple major versions of
the implementation of the business logic as REST offers no room to introduce a layer of indirection. This
coupling between resource and endpoint makes it difficult to assign a version to a resource type. In REST
each resource (instance) can potentially implement its own version of the business logic associated to a
particular version of HTTP verb and arbitrary noun.
10
11. Compatibility & Composability
The compatibility scenarios defined earlier can be combined into these strategies as defined in the latest
Thomas Erl series book Web Service Contract Design and Versioning for SOA:
Strict: Any change is considered unsafe and must cause a new version. Non-breaking changes
cause a new minor version. Breaking changes will require a new major version. Both backwards
and forwards compatibility is intentionally disregarded.
Flexible: Non-breaking changes will only result in a new point version. Breaking changes will of
course require a new major version. This strategy uses backwards compatible contracts, but not
forwards compatible contracts.
Loose: Use both backwards and forwards compatible contracts. Breaking changes will of course
require a new major version.
“Strict” is a very common approach to handling schema versioning. It is a safe approach that will give
you no surprises when changing contracts. In fact, the schema artifact versioning table shown above is
based on the “Strict” strategy. However, it will lead to an explosion of contract versions as your services
evolve, and this will hurt discoverability and especially governance not to mention reuse. In addition,
operations will need to keep your multitude of service versions up and running. Changes to schemas
that are used in aggregate schemas (schema compositions) will ripple through all involved aggregates
and cause a domino effect of new schema versions. And of course, when a schema used in a service gets
a new version, the service must also get a new version. Composite services that involve these services
will then also be affected and must also get a new version. Thus, the ripple effect is much bigger than
you think.
This versioning domino effect soon has caused a little change to ripple through all versionable artifacts
in your system. And it doesn’t stop there; in the end it will affect your consumers.
Composability will suffer when you have poor service discoverability and a proliferation of service
versions. Which services should an unfortunate consumer use and which services will work together as
composite services? Having standardized service contracts including a common information model for
your domain might not be enough when there are thousands of versions of the standardized services
and schemas.
“Flexible” tries to alleviate the version explosion effect of Strict, by treating all non-breaking changes as
safe and backwards compatible. As backwards compatible contract changes by design continues to
support consumers designed to work with the old version of the contract, a new version is not needed –
i.e. it is just a point version. Services can easily be composed together as all the contracts within a major
version are backwards compatible and only one minor service version – the latest – needs to be
considered for every major version. Add “Loose” to get forwards compatible contracts, and all your
compatibility & composability issues are history.
In theory this seems to be the perfect solution, only breaking changes will require a new version and
hence ripple through all versionable artifacts. In theory - had it not been for possible side-effects of
11
12. “safe” changes, both functional and non-functional. As Nicolai M. Josuttis shows in the book SOA in
Practice even adding a new optional XML element can have non-functional side-effects such as
increasing the response time of a service, breaking the SLA of the service. It would be safer to provide a
new service version with the new schema, as if there is a problem, only the upgraded consumers that
required the change will be affected. Keep in mind though, that in our proposed recommendations, the
compatibility is stated, not implied, so if the SLA was changed by a single element, this would mandate
the definition of a new major version (and XML namespace), even though from an XML extensibility
perspective, this change is perfectly compatible.
A certain combination of these will work better to our experience:
Flexible/Strict: Use “Flexible” for all safe schema changes, while “Strict” must be used for any
unsafe modification to schemas. Breaking changes will require a new major version. Support
forwards compatibility.
The “Flexible/Strict” strategy combines the best from the three original strategies. It grades changes into
safe and unsafe even if they are theoretically backwards compatible (i.e. non-breaking). Safe changes
cause point versions, while unsafe changes cause at least a minor version. There are no absolute
classification schemes of which changes are safe and which are unsafe, but we suggest that adding to
schemas are considered safe while modifying existing schema components are considered unsafe.
Always judge if even a “safe” change may cause negative side-effects, remember to consider non-
functional aspects.
Strategy Change Major Minor Point FW
Strict Breaking X
Strict Non-Breaking X
Flexible Breaking X
Flexible Non-Breaking X
Loose Breaking X X
Loose Non-Breaking X X
Flexible/Strict Breaking X +
Flexible/Strict Non-Breaking, Safe X +
Flexible/Strict Non-Breaking, Unsafe X +
Table 3. Compatible changes classified as safe or unsafe
Using “Flexible/Strict” will impact the schema artifact versioning table as all changes that in the “Strict”
sense must be a new minor version now can become just a point version for safe changes. Unsafe non-
12
13. breaking changes must still be a new minor version. Note that even if you judge a code change to be
safe, we still recommend this to be a new minor version.
Schemas are validated and routed based on their major and minor versions, thus aiming for point
version compatibility will also reduce the need for intricate versioning mechanisms in your services.
We recommend using the “Flexible/Strict” strategy for your published services, and also use forwards
compatibility in the form of planned extensibility. Avoid just throwing in schema wildcards everywhere
as this will lead to vague contracts, countering discoverability. John Evdemon advices that “schemas
should be designed for extensibility, not to avoid versioning”. Judicious use of unambiguous wildcards
can help minimize service versioning. We strongly recommend following these guidelines.
Use a combination of compatible contracts and multiple active service versions to ensure that you’re
system is flexible enough to accommodate the inevitable changes that will happen over time. Keep
things simple. Whatever you do, do not try to implement some implicit automagical handling of
versioning inside your services; instead expose your services at abstract endpoints and apply intelligent
routing to achieve service virtualization and apply schema duck-typing outside your services.
You should use the flexible strategy during development of the services due to the agility needed in that
phase. Wait until the services have been published (are in production) to apply strict versioning aspects,
otherwise you will just end up with a very frustrated bunch of consumer and provider developers.
Note that how platforms support forwards compatibility differs. Some require the use of schema
wildcards while others like WCF have implicit support for forwards compatibility. Always test that your
involved platforms work with your forwards compatible schemas. Don’t rely on this just working,
interoperability is important for composability.
Data Model and Message Type DSLs
One of the core problems of distributed computing technologies is the combined handling of both
information and business logic. Some approaches are good at managing distributed information (REST /
HTTP) and some technologies are good at invoking business logic (Web Services). Technologies that have
tried to address both using a combination of remoting technologies and naming & identity services have
generally failed at delivering an environment where both information access and business logic
invocation coexist harmoniously. Most often, a pattern, such as the Data Transfer Object pattern, has
become the prevalent mode of interaction and information representations are simply conveyed back
and forth between endpoints representing services, i.e. business logic.
One of the fundamental reasons for the lack of solution for this difficult problem is the fact that
Enterprise Data is “relational” and utilizes most often bidirectional associations. By contrast, the Web is
built on a “navigational” data model and unidirectional links. In both cases (navigational and relational),
there is always the need to fetch data in a denormalized way via the same endpoint. This means that
when fetching a purchase order, one might also return some customer specific information (name,
address, telephone…) as well as shipping information. Whether you use a RESTful approach or a Web
13
14. Services approach, the problem is exactly the same. REST is of course slightly better equipped to provide
a normalized solution to this problem since a link to the customer can be embedded within a purchase
order representation, but this is generally not practical as representations often need to embed related
data, to enhance user experience, limit navigations and network roundtrips.
The goal of this paper is not to solve this distributed information integration problem. We are going to
assume that somehow people can only deal with it behind endpoints in both REST and Web Services
world (this is the state of where we are today until more progress is made in distributed computing
technologies). In this environment, the problem people have to deal with is how to manage
denormalized message types, especially in the context of versioning, i.e. when the enterprise data
model needs a revision (Fig 5.).
Customer Order Shipment
0..n 0..n
name PO#
address
1 0..n
?????
Customer PO Shipment
name Customer Customer
address name name
POs address address
PO# Shipment POs
PO# PO#
Fig 5. How do we keep the enterprise data model and message types synchronized?
Up until this point, the industry has kept Enterprise Data Models, XML Schemas and Message types
relatively separate. At most, people defined an ontology with links to both.
In this article we argue that (Fig 6.)
XML Schema should not be used for creating and managing enterprise data models.
Enterprise Data Models should be created and managed based on a DSL (EDM-DSL)
Message types should be created and managed based on a DSL and using the Enterprise Data
Model elements as building blocks (MT-DSL)
XML Schemas should be generated from the Message Type DSL (itself referencing elements of
the Enterprise Data Model).
14
15. Enterprise
Enterprise
Data
Data
Model Based on
Model
DSL
Message
Message
Type
Message
references references TypeXML
Type
Schema
Message
Message Generate
Type Message
Message
Based on Type references
DSL Type
Type
Definition
Message
Message
WSDL
Type
Type
Message
Type
Fig. 6. Enterprise Data Model and Message Type DSLs
Let’s explore these points one by one. XML Schema should not be used for creating and managing
Enterprise Data Model because XML Schema was never designed for that. XML Schema cannot describe
efficiently the relational nature of enterprise data models. XML Schema is hierarchical in nature and
cannot model well bidirectional relationships between information entities. XML Schema is a technology
that is well suited to describe and validate the structure of self-standing “documents” be it message
types, web pages, office documents…
Enterprise Data Models should be created and Managed based on a DSL because no current modeling
technology, be it UML or Entity-Relationship diagrams (ERD) have the appropriate semantics to describe
Enterprise Data Models. The core semantic that is missing, and that makes it a non starter for any
existing technology, is paradoxically having the ability to describe a hierarchical structure of related
elements. In other words be it in UML or ERD, we do not have the semantic to define the boundary of a
purchase order or a customer. We can define classes or entities, but in reality a purchase order or a
customer is effectively “composed” of several classes. We need to be able to define a boundary to these
objects and no “standard” modeling language support this semantic because they themselves are too
close to the physical implementation model (Object Orientation in the case of UML and RDBMS in the
case of ERD). In the case of UML, we would have to define a UML profile to extend it with these
semantics. We recommend however to create a dedicated Data Model DSL instead of using a UML
profile because transformations are a lot easier, uncluttered by the UML metamodel.
Message types should be defined based on a dedicated message type DSL which references elements of
the Enterprise Data Model because, in essence, this is really how Message Types are constructed (or at
least should be constructed). When you create a service interface, be it RESTful or Web Services based,
15
16. you really want to create a message type (or resource representation) that reflects the enterprise data
model both semantically and structurally, instead of reflecting the particularities of a given back end
system. This is in line with loose coupling practices which recommend to minimize the “contract-to-
implementation” coupling. An approach based on the semantics of an Enterprise Data Model is
expected to reduce the need for both Governance (or at least reuse Data Governance efforts) and
create service interfaces or resource representations that will be most likely reusable and composable.
Finally, flat XML Schemas should be generated from these Message Types definitions (based themselves
on the Enterprise Data Model). Flat schemas improve interoperability between Web Service stack as
some stack have difficulties to deal with complex nested schema files. XML Schema is a great technology
to validate the structure and (some of) the content of “documents”. It should remain the primary choice
for describing the structure and validating the content of incoming messages.
Active Service Versions
It is important to implement service lifecycle management policies and procedures to help with
governing service versions. We recommended creating an “Active Service Versions” policy to keep the
number of service versions that you have to govern to a minimum. Alas, our experience shows that in
practice this will be hard to adhere to, thus implement the policy as a guideline rather than a law.
Such a policy typically states that there should be maximum three active versions of a service available
for consumers, plus a hidden active minor version of the latest major. The hidden minor version gives
current consumers a transition period for reverting to a compatible version, just in case the
compatibility statement made for the latest minor version was erroneous. In that case, the consumer
will manually point to the previous minor version endpoint.
Fig. 7. Service version classification
16
17. You will typically end up with some services that require 5-6 major active service versions, especially for
popular services that are used by multiple consumers. There will always be some consumers that are
laggards in upgrading to newer service versions, and you might not be able to cut them off. However,
the approach that we are recommending ensure that for every major version available, we only need to
expose the respective latest minor version.
Ensure that new consumers always by default discover the published version of your services (i.e. the
latest major/minor version). The published version is what developers will get using the classic
http://url?WSDL “discovery” of the service. In addition, we recommend that three major versions of a
service can be discovered in your service registry. These must be the latest minor version of each.
Finally, you must monitor the usage of the services to know which are used and by whom. The service
lifecycle stewards must notify all consumers of deprecated versions and gently force them to upgrade to
an active service version. When no one (important) is using a deprecated version, you can decommission
it. This ends the lifecycle management of that service version. You can easily imagine how much harder
the steward’s job would be if he or she had to do the same thing for both the major and multiple minor
versions as well.
The active service versions should be accessible through a single virtual endpoint that the consumers
use to invoke the service. This will lessen the impact that versioning the service will have on its
consumers, as the virtual endpoint stays the same and handles the routing to the correct active service
version. Compatibility reduces the need for virtualization as the same endpoint can service several
generations of compatible consumers. Services are routed based on their major and minor versions,
thus aiming for point version compatibility will also reduce the need for complex virtual endpoint
mechanisms.
Service Virtualization is achieved by combining several ESB patterns such as abstract endpoints,
intelligent routing and schema transformations. Using service virtualization isolates the consumers from
the providers and it processes messages “in-flight” to route and mediate between the providers and
versions that make up a composite service that a consumer invokes or triggers through an event.
Using virtualization is not only for composite services, in fact all your published services at any
classification level would benefit from this seen from a governance perspective.
17
18. Interoperability
The economy is getting more and more globalized and outsourcing seems to be the standard these days.
The business processes of a company more often than not involve partners and suppliers mashed
together into what is called the extended enterprise
The constituents of an extended enterprise will have heterogeneous systems, just as the different
business units of a company most likely will have heterogeneous systems (figure 8). There is no end to
the diversity of legacy systems in use in companies today. A recent Gartner study shows that the
diversity of platforms used to deliver SOA is growing, even mainframe COBOL have had a surge the last
year.
Composability across these heterogeneous service providers in the extended enterprise will require
interoperability. This affects how you design your services and schemas, including which of the WS*
standards you choose to entail in your services. Our interoperability experience is summarized in the
below table.
Artifact Interoperability
SOAP Adhere to WS-I Basic Profile 1.1
SOAP 1.2 Most legacy platforms and tools require SOAP 1.1
WSDL style Prefer “Document/Literal Wrapped” (D/L-W)
WSDL design Avoid wsdl:import and xsd:import as many tools require a single flat WSDL. An
example is Flex.
Messages Use message exchange patters (MEP) e.g. as defined in WSDL 2.0
Message design Single part element for both request and response
Schema style Prefer “Venetian Blind” (complex types)
Schema style Do not use anonymous types (“Russian Doll”)
Schema design Support XSD extensibility, use marker element before schema wildcard; always
test support for schema wildcards across involved platforms
Schema design D/L-W schema components: allows only elements, prohibits use of attributes
Schema design Use of attributes for data or to annotate data elements might not be
supported by all platforms
Schema arrays Use wrapped arrays/collections
XSD types Not all XSD data types are supported by all platforms (e.g. xs:date,
xs:positiveInteger)
18
19. XSD nillable Some nillable schema components might not be supported by a platform,
while other components might be required to be nillable
WS* standards The support varies wildly between platforms, always test and verify chosen
standard for interoperability
WS-Security Make sure to agree on version, token type, message or transport security,
order and level of encryption and signing, and establishment of secure
conversations (security sessions)
WS-Policy, Some platforms and tools do not support these standard, thus policy metadata
WS-SecurityPolicy have to be communicated out-of-band. An example is Java Spring-WS.
Table 4. Contract design guidelines
Fig. 8. Growing diversity in SOA platforms
The figure “Trends in Use of Development Languages are Related to SOA Adoption” is from the Gartner
report “2008 SOA User Survey: Adoption Trends and Characteristics” by Daniel Scholler.
19
20. Conclusion
In this article we have defined a versioning strategy which focuses on reuse by enabling services to
evolve to meet new consumer requirements without breaking existing consumers of the service. In a
way this is a “forward” reuse strategy, as the “new version” of a service is reused by the older
consumers instead of the other way around, where a new consumer reuses a service designed for an
existing service consumer.
From our experience, we feel that compatible, versioned data models, messages and services have not
been a primary concern of SOA initiatives. In addition, of those that defined a versioning strategy, very
few have used XML and XML Schema extensibility. It is our strong belief that a compatibility-based
versioning strategy can increase service discoverability, composability and true reuse. It can also reduce,
albeit not eliminate, the need for service governance. Overall, it is expected that the cost of
construction, operation and maintenance of a service will greatly be reduced by such versioning
strategy. It is time to move beyond primitive reuse to reap the benefits of your service inventory.
1
Harmut Wilms, InnoQ, Private Communication
20