SOA Initiative: Get your schemas and service contracts correct.

Posted at: 7/29/2009 at 12:38 PM by saravana

SOA in an organisation is a journey; an organisation can't change their existing strategy overnight. There are tons of articles written about SOA initiative, so I'm not going to add one more. In this article I'll assume, your organisation has decided to implement SOA and as part of the journey you decided to implement your first service. Your journey is not going to stop after building your first service, so the organisation should plan and impose all of their SOA strategies and design principles when building their first service and treat it as a base platform for the forth coming services.

When it comes to building services, the basic building blocks are schemas and service contracts. In technical terms it translates to xsd's and wsdl's. Often times refactoring schemas will have a ripple effect right up to the top level, so it worth putting enough time and effort in nailing down your schema (data) and service contract requirements.

We'll just assume this sample scenario: Your organisation is building an address service with a single operation called FindAddress. Using the service, consumers can search for addresses based on building number and post code (SearchRequest). The service in turn will return the list of addresses (SearchResponse) that matched the criteria. The scenario is simple, so we can concentrate on the core principles. The structure of our Address Service looks like this

clip_image002

First of all, let's break down the things required to construct our Address Services.

  1. We need a unique namespace to uniquely identify our Address service.
  2. We need unique identifier to access our operation FindAddress. This in web services world will be SOAPAction. Normally its good practice to club the service namespace with the operation name to generate this identifier.
  3. We need a request (SearchRequest) and a response (SearchResponse) message structure (types) required for our operation FindAddress.

There are various things you need to consider while designing the schemas and service contracts. Some of them will look so obvious and basic; things like folder structure, file names, namespace, placement of complex data structures, taking advantage of object oriented support for XSD's etc. But they will prove very critical when the services start to evolve.

The basic building block required for our address services is the request (SearchRequest) and response (SearchResponse) message structures. It was not so uncommon people dived directly into tools like Visual Studio, open up a .asmx/WCF web project or similar tools/techniques in other platforms and start building (implementing) the service before finalising the contract. The tools in turn auto generate the service contracts (wsdl). It's a great help from the tooling point of view, but its not going to help us in long run. Maintainability and versioning will become a major issues, since the service contract and service implementation are tightly couples. A better approach will be to build the schemas and contracts in a modular way, so each module can evolve independently with various version numbers.

I just picked up this quote (while reading a post from Martin Fowler) from Kent Beck, which I feel is very relevant, while designing the schemas:

People can read your programs much more quickly and accurately if they can understand them in detail, then chunk those details into higher level structures. --Kent Beck

Basically Kent Beck is insisting on breaking large methods into well named smaller methods, a technique he refers to as Composed Method Patterns. That's exactly what we are going to do here, we are going to break a large schema structure into smaller more maintainable structures in various files.

The below figure explains what we are trying to achieve in a nutshell:

clip_image004

Figure 1

When we translate the above picture into technical terms using xsd, wsld, import, data types etc. It will look like the one shown below.

clip_image006

Figure 2

The hierarch and complexity of having multiple files to construct such simple message types might look overwhelming initially, but trust me it's going to pay off in long run, when you start leveraging more services in your organisation.

Target Namespaces for various levels

Filename Target Namespace
AddressService_1.wsdl http://yourorg.com/wsdl/addressService/1
AddressService_1.xsd http://yourorg.com/schemas/service/address/1
Address_1_0.xsd http://yourorg.com/schema/entity/address/1.0
OrgDataTypes_1_0.xsd http://yourorg.com/schema/entity/common/1.0

The numbers at the end of the namespaces and file names are there to mainly help us in versioning schemas and service contracts. I'll explain them in my next article. For the time being please ignore them.

Organisation wide common data models (OrgDataTypes_1_0.xsd):

The very first thing you need to do before constructing any services in your organisation is to find all the common entities (data structures) that will be required across the organisation. It will be difficult to identify all of them at on go, but you can always start with the basic list and add more structures to it as and when you identify them. That's the whole point of having those version numbers at the end and in the target namespace.

Majority of the types in OrgDataTypes_1_0.xsd will have simple or complex type with restrictions appropriate for your organisation. Whenever you are constructing complex data models, don't be tempted to use the standard xsd types directly inside your complex types. Example: While constructing the UKAddress type which requires a postcode, you could have easily end up using xsd:string type for post code. But in our solution we defined a simple type called PostCode which is an extension of xsd:string with a regular expression pattern restricting to only UK post code. In this way your schema validation will be effective and be able to capture the errors much earlier in the cycle. Also it will be a consistent pattern across the organisation.

<xsd:simpleType name="Postcode">
<xsd:restriction base="xsd:string"> <xsd:pattern value="((([A-Z]{2}[0-9]{1,2})|([A-Z]{1,2}[0-9][A-Z])|([A-Z][0-9]{1,2}))\s([0-9][A-Z]{2})|(BFPO\s\d{1,4})|(GIR\s0AA))"/> </xsd:restriction>
</xsd:simpleType>

Another important reason to build the common types used across the organisation is reusability; these types may be required across many services you build in the future. Example: The PostCode type may be required in the InventoryService to determine the stock location post code.

It's important you decide on the format of the namespace (target) you want to use. For our example I've chosen http://yourorg.com/schema/entity/common/1.0

Address Service specific data models (Address_1_0.xsd):

After defining the common entity structures, the next step is to build the entity types required for our address service. Address_1_0.xsd file will contain only service specific simple and complex types required to construct the address service. The first thing you need to do is to import OrgDataTypes_1_0.xsd file into Address_1_0.xsd, which contains all the basic building blocks (entities) used common across the organisation.

<xsd:import namespace="http://yourorg.com/schema/entity/common/1.0" schemaLocation="../../Common/1.0/OrgDatatypes_1_0.xsd"/>

Once the common entity schema is imported, the next important thing to do is to decide on a unique namespace (target) for the service specific schema Address_1_0.xsd. Make sure it's different from the one we have used for the common entity schema. For our example I've chosen http://yourorg.com/schema/entity/address/1.0.

Now you can start defining the entities required for the address service inside Address_1_0.xsd. Example: As shown in figure 2, Address_1_0.xsd contains the complex type UKAddress to represent a UK address structure, which is basically constructed using all the common entity types found in OrgDataTypes_1_0.xsd.

Address Service specific messages (AddressService_1.xsd):

This is the place where we construct the types that will be used directly by the service contracts WSDL. Similar to what we have done while constructing Address_1_0.xsd, the first thing we'll do here is to import the required schemas (Address_1_0.xsd and if required you can download the OrgDataTypes_1_0.xsd as well if you are referring to types directly from common entities).

In AddressService_1.xsd we will define types that are explicitly required to build the service contract (ex: SearchRequest, SearchResponse). Majority of the times these types won't have any reusable value outside the context of the service. Types like service specific errors, warnings, etc are good candidate for this file. Again it's essential to choose a consistent and unique target namespace format. For our example I've chosen http://yourorg.com/schemas/service/address/1.

Constructing Service Interface (AddressService_1.wsdl)

At this stage we got all the required building blocks to construct our Address Service WSDL. You can hand craft it, if you are familiar with the semantics of WSDL. Otherwise you can use the tools like XmlSpy, ThinkTectures WSCF (web service contract first) etc to construct the service WSDL.

Folder Structure:

Its also important to place the schemas and wsdl files in the right hierarch in the files system and contract repositories. You'll referencing/importing schemas regularly in order to construct new service specific schemas and contracts (WSDL's). Ex:

<xsd:import namespace="http://yourorg.com/schema/entity/common/1.0" schemaLocation="../../Common/1.0/OrgDatatypes_1_0.xsd"/>

The below figure shows the simple structure  utilized for this sample scenario.

image

Advantages of taking this modular approach:

There are various advantages in building the schemas and contracts in a modular way. Let see some of the key values

1. Reusability: The number one reason is the reusability of types. We have seen the organisation wide types (town, postcode etc) are being reused when constructing the UK Address type in address service. In the future some other service like example Inventory can reuse the UK Address type directly by importing the address schema (with appropriate version number).

2. Versioning: Individual modules can evolve independently with different version numbers. Providing greater degree of maintainability.

3. Extensibility: XSD supports object oriented approach while designing schemas, which can be utilized to extend the base types and create much more complex types if required.

Nandri!

Saravana

Tags:  Categories: SOA
Actions: Email this article Email | Kick it! | DZone it! | Save to del.icio.us | Technorati Links
Post Information: Permanent LinkPermalink | CommentsComments(13) | Comments RSS

Comments

Thursday, July 08, 2010 10:37 AM
oil painting
Very instructive and helpful stuff. Thank you for the great sharing here. Will come back for more.
Friday, July 16, 2010 6:51 AM
gratis daten
I am impressed with your writing skill.....You have a very rewarding blog. But one question remains In which way do you handle the increasing number of Spam in your blog comments? I do not like it at all, It wastes lots of my time and I  do not like messing around with this every single day.
Wednesday, July 28, 2010 9:15 AM
no fax personal loans
Whenever any form of government becomes destructive of these ends [life, liberty, and the pursuit of happiness] it is the right of the people to alter or abolish it, and to institute new government...
Tuesday, August 03, 2010 8:02 PM
Love the way you lie
This site is great.
Thursday, August 05, 2010 1:27 PM
online bingo
IT Governance subsumes SOA governance, not vice versa. Of course, there are also aspects of SOA governance that are implemented at a much lower level within projects to ensure consistency of service definitions, etc. Once again, however, this should be handled by the existing technology governance processes. We’re merely adding some additional criteria for them to be applying to projects.
Saturday, August 07, 2010 7:31 AM
Nike Shox NZ
This blog is very nice and informative. I am quite sure visitors will learn lots of new stuff here than anybody else!
Tuesday, August 10, 2010 10:42 PM
advance cash company
Treat a person as he is, and he will remain as he is. Treat him as he could be, and he will become what he should be.
Saturday, August 14, 2010 4:38 AM
14" diamond blades
All good things in life have special attention paid to detail. If you take the movie forest gump, it's a basic story line but what makes that movie good it the attention to detail.
Saturday, August 14, 2010 10:54 AM
timberland 6 boots
She told me that she had worked for timberland 6 inch years for an insurance company. She never mentioned family, and I did not ask. I have thought about her timberland mens custom often over the years and how she struggled in a society that places an incredible premium on looks, class, wealth and all the other fineries of life. She suffered from a disfigurement that cannot be made to look attractive. I know that her condition black timberland boots hurt her deeply. http://www.timberland6inch.com/
Wednesday, September 01, 2010 2:52 PM
sell my house
Good informative post. I will visit your site often to keep updated.
Wednesday, September 01, 2010 2:52 PM
we buy houses
great and interessting post
Wednesday, September 01, 2010 2:53 PM
buy my house
i bookmarked your blog, keep posting good stuff Smile
Wednesday, September 01, 2010 2:53 PM
cartoon yourself
interessting post, keep posting

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading