Designing WSDLs efficiently with Namespaces
Namespaces are ubiquitous and they wander in almost every XML document, SOAP message and WSDL you name it. Initially, namespaces seems confusing but once you understand its purpose then you will appreciate its power and flexibility. Namespaces plays a vital role in the WSDL design. To simply put, the basic purpose of namespace is to avoid element name conflicts in the XML documents. There are many other advantages with namespaces like readability, reusability, extendibility, version tractability and modularity. Let me walk you through these terms explaining its meaning and high lighting its usefulness in designing WSDLs efficiently.
Readability, Modularity & Reusability:
Namespaces allows clarity and readability to the XML document saying which elements falls under which modules and sort of reusing them by importing from other wsdls or other schemas.
Example:
Suppose we have a sun.xsd which contains the following:
<element name="sun">
<java/>
<solaris/>
<dtrace/>
...
</element>
And we have a microsoft.xsd which contains the following:
<element name="microsoft">
<vista/>
<c#/>
<java/>
...
</element>
If we want to access these two xsds in a xyz.xsd, then we have a conflict with java element!
<element name="xyz corp">
<solaris>
<vista/>
<c#/>
<java/> <!-- sun/microsoft java? -->
...
</element>
To avoid this, we can use namespaces as follows:
<element name="xyz corp" xmlns:sun="hhtp://www.sun.com" xmlns:msft="http://www.microsoft.com" ... >
<sun:solaris/>
<msft:vista/>
<msft:c#/>
<sun:java/> <!-- Now, this is clear here -->
...
</element>
Extendability:
Now, what's the relationship between xml namespaces and wsdl design. I will explain this in a bit. If you want to design wsdl's in modular and scalable way, namespaces is the way to go about it.
Consider for example, You have a supply chain management application which needs schemas like ubl-orders, ubl-invoice & ubl-shipments. The schemas for these business functions are complex. Each has its own elements and some might be in conflict with others etc.
One way to solve this problem is, we can embed all the schema elements in one huge gigantic wsdl file... like
<definition ...>
<schema>
<orders>
...
</orders>
<invoice>
...
</invoice>
<shipments>
...
</shipments>
</schema>
...
</definition>
Now, lets see the pros and cons for this type of design. This design we can call embedded schemas.
pros:
1. For smaller schemas, its easy to have all the schema elements in a single wsdl file.
2. All the elements in single namespace, so no confusion with namespaces, assuming no name conflicts.
cons:
1. Managing the wsdl document is difficult if the complexity of the schema increases like if we want to add more modules etc.
2. In web services world, schemas come from different parties, so name conflicts will occur.
3. Doesn't scale (physically like file size etc) well.
Lets see the other way to solve this problem by importing the schemas.
We can define 3 schemas like orders.xsd, invoice.xsd and shipment.xsd with respective schema elements and we can efficiently import these into the wsdl. This way, we know which elements belongs to which xsd and easy to read the wsdl. Also gives us a good room for scaling with some more xsds.
<definition ...>
<schema>
<import namespace=”...” schemalocation=”orders.xsd”>
<import namespace=”...” schemalocation=”invoice.xsd”>
<import namespace=”...” schemalocation=”shipment.xsd”>
...
</schema>
...
</definition>
As you can see this reduces the size of your wsdl drastically depending on your complexity of your schema elements and provides a cleaner way to expand your wsdls.
pros:
1. Scales well and managing is easy as the document complexity increases.
2. No name conflicts since each imported xsd has its own namespace.
3. Cleaner design
cons:
1. Reading elements with multiple namespaces is tedious.
Version Tracking:
Well, everyone might have come across supporting multiple versions of software products or providing a backward compatibility with the previous versions. There are couple of ways to do it using namespaces either by embedded schemas or importing schemas and by changing the version numbers in the namespace declarations.
Example:
1. The following example shows version tracking by embedding the schemas.
<definition ...>
<schema xmlns:inv_v1=”http://www.sun.com/invoice/v1.0”
xmlns:inv_v2=”http://www.sun.com/invoice/v2.0”>
<element name=”invoicev1” types=”inv_v1:Invoice”>
<element name=”invoicev2” types=”inv_v2:Invoice”>
</schema>
...
<definition ...>
2. The following example shows version tracking by importing the schemas.
<definition ...>
<schema>
<import namespace=”http://www.sun.com/invoice/v1.0”
schemalocation=”invoice_v1.xsd”>
<import namespace=”http://www.sun.com/invoice/v2.0”
schemalocation=”invoice_v2.xsd”>
...
</schema>
...
</definition>