Key paradigm shift from objects to contracts in the Service-Oriented world

There has been a key paradigm shift from object to contract as the building block for a distributed system in the service-oriented world. Contracts are the new building blocks if we need to develop a long lasting distributed system. How focusing on contracts can improve the business objectives and make partners happier is the least understood aspect of web services which i am going to explain in this article.

There are two common  techniques to develop a web service:

  1. Code-first
  2. Contract-first

Most developers start by writing the service implementation in code and then have a toolkit to produce the WSDL. This approach is called code-first development. Code-first is more common today. This is because working directly with WSDL is extremely difficult. We lack proper tool support to work directly with WSDL and hence code-first is more pleasant. In this technique the developer first codes the logic of how the data is treated within his service. Then he produces the WSDL in an automated way using a toolkit. The WSDL thus produced contains language-specific types. When the business partner wants to interact with the service contract, he realizes that his application doesn’t map nicely to the service contract coded by the developer as it contains language-specific types and he starts looking elsewhere for the service. The key principle of Service Oriented Architecture is to ensure ease-to-consume a contract. The Code-first approach is technology independent and lacks ease-of use.

The fundamental goal of the Contract-first model is to facilitate interoperability. The reach of a web service is unlimited. Embracing this new model of contract-first ensures happier partners. In this approach, the developer first codes the standard contracts that will be shared with the partners. Here the developer focuses on how the data is moved across service boundaries rather than within the service. He invests a lot of time and energy in contract design. He first codes the XML Schema and WSDL definitions. After everyone agrees on WSDL he implements the code. This approach embraces service orientation and is disconnected from how you treat data within a service. It is focused on connecting the dots within a distributed system as a whole. Ease-of use of the service is under the control of contract definition. The Contract definition is a shared language which is the primary focus of this model. This approach ensures that the service designed is interoperable across a wide range of platforms, operating systems and programming languages. It helps partner collaboration and meets the enterprise goals.

Three Schema Design Approaches

In a project where multiple schemas are created it is critical to decide which namespace design approach is suitable for the project: (1)should we give each schema a different targetNamespace, (2)should we give all the schemas the same targetNamespace or (3)should some of the schemas have no targetNamespace. To make this critical design decision, let me illustrate the three schema design approaches in this article.

Heterogeneous Namespace Design

1. Give each schema a different targetNamespace
2. If required to re-use another schema in the current schema we need to import it

Benefits
1. Maximise the re-use of the types with separate namespaces
2. Namespace mapped to domain specific service
3. It would be easier to model all the domain-specific types in separate files with individual namespaces
4. Easier to understand
Drawbacks
1. There will be a large number of namespaces to manage
2. There will be a large number of namespaces to import
3. The granularity of the types in import would depend on the types defined and exposed in a particular domain-specific XSD

Homogenous Namespace Design

1. Give all schemas the same targetNamespace
2. As the schemas have the same targetNamespace, the method of accessing components is “include”.

Benefits
1. No need to either import a service or schemas
Drawbacks
1. Need to handle Name collisions
2. Generate code in a single Java package, for a service
3. chances for redundant types
4. does not allow for domain-specific namespaces

Chameleon Namespace Design

Give the main schema a targetNamespace and give no targetNamespace to the supporting schemas. The no-namespace schemas will take-on the targetNamepspace of the main schema.

Benefits
1. In this scheme, schemas are able to blend in with the main schemas that use them
2. Ability to provide application-specific namespace to the schema
Drawbacks
If the schema <include>s multiple no-namespace schemas then there will be a chance of name collisions. In fact, the schema may end up not being able to use some of the no-namespace schemas because their use results in name collisions with other Chameleon components

The most widely used schema design approach is heterogeneous schema design approach. Let me illustrate this with an example.

Step1: Create a schema file named Books.xsd

<!-- to store book information with targetNamespace declared as tns:Books-->
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="tns:Books"
            elementFormDefault="unqualified">
    <xsd:complexType name="Book">
        <xsd:sequence>
           <xsd:element name="Author" type="xsd:string"/>
           <xsd:element name="Title" type="xsd:string"/>
           <xsd:element name="Price" type="xsd:double"/>
           <xsd:element name="Quantity" type="xsd:integer"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Step2: Create another schema file Sales.xsd

<!-- to store the sales information with targetNamespace declared as tns:Sales-->
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="tns:Sales"
            elementFormDefault="unqualified">
    <xsd:complexType name="Sales">
        <xsd:sequence>
             <xsd:element name="Customer" type="xsd:string"/>
             <xsd:element name="Region" type="xsd:string"/>
             <xsd:element name="TransactionStatus" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Step3: Import the two schema files in Catalog.xsd file

<!--using the Heterogeneous namespace design approach-->
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:b="tns:Books" xmlns:s="tns:Sales" xmlns:ns1="tns:Catalog" targetNamespace="tns:Catalog" elementFormDefault="unqualified">
	<xsd:import namespace="tns:Books" schemaLocation="Books.xsd"/>
	<xsd:import namespace="tns:Sales" schemaLocation="Sales.xsd"/>
	<xsd:element name="Catalog">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element name="Payment">
					<xsd:complexType>
						<xsd:sequence>
							<xsd:element name="CustomerID" type="xsd:integer"></xsd:element>
							<xsd:element name="PaymentType" type="xsd:string"></xsd:element>
							<xsd:element name="Currency" type="xsd:string"></xsd:element>
							<xsd:element name="ShippingAddress" type="xsd:string"></xsd:element>
						</xsd:sequence>
					</xsd:complexType>
				</xsd:element>
				<xsd:element name="Book" type="b:Book" maxOccurs="unbounded"/>
				<xsd:element name="Sales" type="s:Sales" maxOccurs="unbounded"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
</xsd:schema>

XML Web Services in 5 Days

XML in 5 Days - A Hands On Approach

Introduction to XML

XML is the universal format for data interchange.  It is supported by all major operating systems, programming languages and development platforms.  It is the standard platform for building interoperable distributed applications. 

The ability to invoke cross platform communications makes the reach of XML Technology unlimited and its use in Web Services compelling.

Web Services are the building blocks for constructing distributed Web-based applications. They are units of programmable application logic located on web servers that can be accessed remotely using standard internet protocols and data formats such as XML, HTTP and SOAP. Web services use XML-based messaging to send and receive data, which enables heterogeneous applications to interoperate with each other.

Basic concepts of XML

 XML represents structured content rather than visual display. A well-formed XML document contains an end tag for every begin tag. Well-formed XML documents can be modeled as trees. The tree has a single root node containing one or more child nodes. A node without a child is called leaf node. XML Document Object Model (XML DOM) is required to work with XML data.

Document Object Model (DOM) 

Document Object Model (DOM) is a representation of the XML document in memory.  It is used to read, write, and manipulate an XML document. DOM loads the entire XML document into memory.

Simple API for XML (SAX) 

Simple API for XML (SAX) is used to read data from XML documents. SAX parser reads the contents sequentially and generates events as it reads the XML document.  It does not load the entire XML document into memory. SAX is good for reading large XML Documents.

Limitations of SAX:  SAX does not maintain any data structures that are required to perform complex searches. They cannot be used to modify the XML document.

Document Type Definition (DTD)

Document Type Definitions (DTD) outlines elements, attributes & relationships allowed in an XML document. DTDs are written in their own syntax rather than XML syntax.

XML Schema Document (XSD)

XML Schema Documents describe and validate the structure of XML documents.  They restrict the value of elements and attributes in an XML document. They are written in XML syntax. An XML document that adheres to XML schema is called Valid XML document. The XML Schema documents have suffix xsd.

XML Schema – xs:key and xs:keyref

xs:key and xs:keyref in XML models the relationship between primary key and foreign key in a database.  xs:key ensures that the pieces of data in an XML document are unique and not null .  They enforce data integrity in the XML Document.

xskey

xs:unique and xs:ID

The xs:unique element and the xs:ID datatype ensure that the pieces of data in an XML document are unique

xsid

XML Schema Exercise:

1. Create a Cart element. Each Cart element must have multiple instances of child Category element

2. Category element can have multiple instances of child Book and Sales element n

3. Each Book element must have a BookNumber attribute whose value is unique within Category.

4. Each Sales must have an ID attribute whose value matches one of these unique BookNumbers

xs:selector and xs:field

The identity constraint “keyBookNumber” does not allow the incoming xml files to have duplicate values for book number. It is defined using xs:key.

xs:selector: The context in which the primary key constraint should be applied. In this case, the primary key is applied on the Book element. Hence the xs:selector is Book

xs:field: The field that uniquely identifies the record. The field that uniquely identifies the Book record in our case is Number.

<xs:key name="keyBookNumber">
	<xs:selector xpath="Book"/>
	<xs:field xpath="@BookNumber"/>
</xs:key>

The below XML Schema diagram was drawn using Altova XMLSpy. Here Catalog is the root element. It has multiple Book elements which can be uniquely identified using the BookNumber attribute. All attributes have a prefix @.

 

xsselector

After applying the primary key constraint xs:key the XML Schema Document will look like this:

Schemaexercise1

Now lets see the relationship between the book and sales records. As per the exercise  ” each Sales must have an ID attribute whose value matches one of these unique BookNumbers”

relationship

Define xs:keyref constraint “referBookNumber” with selector as Sales and field as @ID. Specify refer as keyBookNumber.
This ensures that each Sales must have an ID attribute whose value matches one of these unique BookNumbers.

output

So the solution for this exercise is as below:

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2009 (http://www.altova.com) by Aruna (Nil) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
	<xs:element name="Cart">
		<xs:annotation>
			<xs:documentation>Comment describing your root element</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Category" maxOccurs="unbounded">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Book" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Title" type="xs:string"/>
										<xs:element name="Author" type="xs:string"/>
										<xs:element name="Description" type="xs:string"/>
										<xs:element name="Price" type="xs:double"/>
										<xs:element name="Quantity" type="xs:integer"/>
										<xs:element name="ISBN" type="xs:integer"/>
									</xs:sequence>
									<xs:attribute name="BookNumber" type="xs:integer"/>
								</xs:complexType>
							</xs:element>
							<xs:element name="Sales" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Customer" type="xs:string"/>
										<xs:element name="Region" type="xs:string"/>
										<xs:element name="TransactionStatus" type="xs:string"/>
									</xs:sequence>
									<xs:attribute name="ID" type="xs:integer"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
					<xs:key name="keyBookNumber">
						<xs:selector xpath="Book"/>
						<xs:field xpath="@BookNumber"/>
					</xs:key>
					<xs:keyref name="referBookNumber" refer="keyBookNumber">
						<xs:selector xpath="Sales"/>
						<xs:field xpath="@ID"/>
					</xs:keyref>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>