{"id":508,"date":"2010-09-01T07:53:10","date_gmt":"2010-09-01T05:53:10","guid":{"rendered":"http:\/\/www.pleus.net\/blog\/?p=508"},"modified":"2011-06-01T08:36:50","modified_gmt":"2011-06-01T06:36:50","slug":"schema-first-contract-design","status":"publish","type":"post","link":"https:\/\/www.pleus.net\/blog\/?p=508","title":{"rendered":"Schema first contract design"},"content":{"rendered":"<p>One of the most important artifacts in Service-oriented Architecture (SOA) is the service contract. The contract defines how service producers and consumers interact with each other. Most people agree that a contract first approach is the preferred way of creating service contracts. WSDL based service contracts are very common. In many projects they are generated by the respective frameworks, such as Apache CXF or Microsoft WCF. This is dangerous, as the developer looses control over the contract. This can result in missing interoperability and limited reusabilty expecially in cross platform scenarios.<br \/>\nFrom what I see, most developers know how to work with their favourite IDE, but only a few know how to create a proper service contract from scratch. I think that is caused by the tool vendors, which in most cases have better support for code based approaches.<br \/>\nIn this post\u00a0I would like to show how to create a portable contract from scratch and share some best practices.<\/p>\n<p><strong>The domain model<\/strong><\/p>\n<p>The first thing to think about is the domain or entity model that the service should expose. The model\u00a0should be\u00a0modeled in XML Schema. XML Schema is standard, portable and supported on all platforms. In fact it is a good idea to use\u00a0XML Schema as the\u00a0single source\u00a0of model information.<\/p>\n<p>The following listing defines the entity Product:<br \/>\n\u00a0<\/p>\n<pre class=\"brush:xml\"><![CDATA[<xs:schema id=\"Types\"\r\ntargetNamespace=\"http:\/\/tempuri.org\/Types.xsd\"     \r\nelementFormDefault=\"qualified\"\r\nxmlns=\"http:\/\/tempuri.org\/Types.xsd\"     \r\nxmlns:mstns=\"http:\/\/tempuri.org\/Types.xsd\"     \r\nxmlns:xs=\"http:\/\/www.w3.org\/2001\/XMLSchema\">\r\n\r\n  <xs:complexType name=\"Product\">\r\n    <xs:sequence>\r\n      <xs:element name=\"n\" type=\"xs:string\" minOccurs=\"1\" maxOccurs=\"1\">\r\n        <xs:annotation>\r\n          <xs:documentation>Name of the product<\/xs:documentation>\r\n        <\/xs:annotation>\r\n      <\/xs:element>\r\n      <xs:element name=\"q\" type=\"xs:int\" minOccurs=\"0\" maxOccurs=\"1\">\r\n        <xs:annotation>\r\n          <xs:documentation>Quantity on stock<\/xs:documentation>\r\n        <\/xs:annotation>\r\n      <\/xs:element>\r\n    <\/xs:sequence>\r\n  <\/xs:complexType>\r\n<\/xs:schema><\/pre>\n<p>The entity Product has two attributes name and quantity. Please note that the xml elements (line 10 and 15) are abbreviated. This helps to reduce the message size on the wire, expecially important in WANs. The downside is obviously reduced readability. That is not really a problem as the contract should be documented anyway using the standard XML Schema annotation elements as shown in line 11 to 13.<br \/>\nThis is the result:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1.jpg\" mce_href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1.jpg\" mce_src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1.jpg\" alt=\"\" title=\"prod\" width=\"289\" height=\"144\" class=\"alignnone size-full wp-image-524\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1.jpg 289w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prod1-150x74.jpg 150w\" sizes=\"auto, (max-width: 289px) 100vw, 289px\" \/><\/a><\/p>\n<p>Wouldn&#8217;t it be nice to have a common base class in order to create a more generic service contract?<br \/>\nLuckily XML Schema allows that. Let&#8217;s create another schema <em>BaseTypes.xsd<\/em> in which we define the base types.<\/p>\n<pre class=\"brush:xml\"><![CDATA[\r\n<xs:schema id=\"BaseTypes\"\r\ntargetNamespace=\"http:\/\/tempuri.org\/BaseTypes.xsd\"\r\nelementFormDefault=\"qualified\"\r\nxmlns=\"http:\/\/tempuri.org\/BaseTypes.xsd\"     \r\nxmlns:mstns=\"http:\/\/tempuri.org\/BaseTypes.xsd\"     \r\nxmlns:xs=\"http:\/\/www.w3.org\/2001\/XMLSchema\">\r\n\r\n  <xs:simpleType name=\"EntityType\">\r\n    <xs:restriction base=\"xs:string\">\r\n      <xs:enumeration value=\"Product\" \/>\r\n      <xs:enumeration value=\"Customer\" \/>\r\n    <\/xs:restriction>\r\n  <\/xs:simpleType>\r\n\r\n  <xs:simpleType name=\"EntityStatus\">\r\n    <xs:restriction base=\"xs:string\">\r\n      <xs:enumeration value=\"Unchanged\" \/>\r\n      <xs:enumeration value=\"Updated\" \/>\r\n      <xs:enumeration value=\"Inserted\" \/>\r\n      <xs:enumeration value=\"Deleted\" \/>\r\n    <\/xs:restriction>\r\n  <\/xs:simpleType>\r\n\r\n  <xs:complexType name=\"Entity\">\r\n    <xs:sequence>\r\n      <xs:element name=\"id\" type=\"xs:int\" minOccurs=\"1\" maxOccurs=\"1\">\r\n        <xs:annotation>\r\n          <xs:documentation>Unique key<\/xs:documentation>\r\n        <\/xs:annotation>\r\n      <\/xs:element>\r\n      <xs:element name=\"st\" type=\"EntityStatus\" minOccurs=\"0\">\r\n        <xs:annotation>\r\n          <xs:documentation>Status of the entity<\/xs:documentation>\r\n        <\/xs:annotation>\r\n      <\/xs:element>\r\n    <\/xs:sequence>\r\n  <\/xs:complexType>\r\n<\/xs:schema><\/pre>\n<p>This base type <em>Entity <\/em>(line 24) defines common attributes for all entities. In XML Schema one can define enumerations as well (line 8 and 15). The enumeration <em>EntityStatus<\/em> defines the state of the entity. This is important in scenarios in which the entities are detached from the database. By marking the entities, it is easy to implement change tracking on the consumer side and just return the changed or deleted parts to the server. This saves network and processing time. <em>EntityType<\/em> is used later in our service interface to request different types of entities.<br \/>\nWe can now import the base types into <em>Types.xsd<\/em> and change the Product type:<\/p>\n<pre class=\"brush:xml;highlight:[9,12,13]\"><![CDATA[\r\n<xs:schema id=\"Types\"\r\ntargetNamespace=\"http:\/\/tempuri.org\/Types.xsd\"\r\nelementFormDefault=\"qualified\"\r\nxmlns=\"http:\/\/tempuri.org\/Types.xsd\"\r\nxmlns:mstns=\"http:\/\/tempuri.org\/Types.xsd\"     \r\nxmlns:xs=\"http:\/\/www.w3.org\/2001\/XMLSchema\"     \r\nxmlns:bt=\"http:\/\/tempuri.org\/BaseTypes.xsd\">\r\n\r\n<xs:import namespace=\"http:\/\/tempuri.org\/BaseTypes.xsd\" schemaLocation=\"BaseTypes.xsd\" \/>\r\n\r\n  <xs:complexType name=\"Product\">\r\n    <xs:complexContent>\r\n      <xs:extension base=\"bt:Entity\">\r\n        <xs:sequence>\r\n          <xs:element name=\"n\" type=\"xs:string\" minOccurs=\"1\" maxOccurs=\"1\">\r\n            <xs:annotation>\r\n              <xs:documentation>Name of the product<\/xs:documentation>\r\n            <\/xs:annotation>\r\n          <\/xs:element>\r\n          <xs:element name=\"q\" type=\"xs:int\" minOccurs=\"0\" maxOccurs=\"1\">\r\n            <xs:annotation>\r\n              <xs:documentation>Quantity on stock<\/xs:documentation>\r\n            <\/xs:annotation>\r\n          <\/xs:element>\r\n        <\/xs:sequence>\r\n      <\/xs:extension>\r\n    <\/xs:complexContent>\r\n  <\/xs:complexType>\r\n<\/xs:schema>\r\n<\/pre>\n<p>You can see the import in line 9. In line 12 and 13 the base type is added to the Product type.<\/p>\n<p>This is the result:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase.png\" mce_href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase.png\" mce_src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase.png\" alt=\"Entity with base class\" title=\"prodbase\" width=\"317\" height=\"228\" class=\"alignnone size-full wp-image-536\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase.png 317w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase-300x215.png 300w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/prodbase-150x107.png 150w\" sizes=\"auto, (max-width: 317px) 100vw, 317px\" \/><\/a><\/p>\n<p>Now we have our model completely defined in XML Schema. By using imports and type inheritance one can create very modular entity models. Those models can be reused without any change by interface definitions such as WSDL and WADL for SOAP or REST services. Moreover the code models (Java, C#, etc.) can be fully generated from the schema. Every good framework has a generator tool on board. For instance Apache Axis\/wsdl2java, Apache CXF\/wsd2java, Silverlight\/slsvcutil, .NET\/svcutil, etc. The schema can be stored in a service repository in order to increase reusability amongst the organisation.<\/p>\n<p><strong>The messages<\/strong><br \/>\nEvery service operation receives a message and returns a message to the sender. Those messages should also be defined using XML Schema. The following snippet shows the message definitions. The fault messages are ommitted for the sake of simplification.<\/p>\n<pre class=\"brush:xml\"><![CDATA[\r\n\r\n  <xs:complexType name=\"ArrayofInt\">\r\n    <xs:sequence>\r\n      <xs:element name=\"e\" type=\"xs:int\" minOccurs=\"0\" maxOccurs=\"unbounded\" \/>\r\n    <\/xs:sequence>\r\n  <\/xs:complexType>\r\n\r\n  <xs:complexType name=\"ArrayofEntity\">\r\n    <xs:sequence>\r\n      <xs:element name=\"e\" type=\"bt:Entity\" minOccurs=\"0\" maxOccurs=\"unbounded\" \/>\r\n    <\/xs:sequence>\r\n  <\/xs:complexType>\r\n\r\n    <xs:element name=\"ReadEntitiesRequest\">\r\n        <xs:annotation>\r\n            <xs:documentation>This represents a request to read business entities<\/xs:documentation>\r\n        <\/xs:annotation>\r\n        <xs:complexType>\r\n            <xs:sequence>\r\n                <xs:element name=\"type\" type=\"EntityType\" minOccurs=\"1\" maxOccurs=\"1\">\r\n                    <xs:annotation>\r\n                        <xs:documentation>Type of the entities to read<\/xs:documentation>\r\n                    <\/xs:annotation>\r\n                <\/xs:element>\r\n                <xs:element name=\"ids\" type=\"ArrayofInt\" minOccurs=\"1\" maxOccurs=\"1\">\r\n                    <xs:annotation>\r\n                        <xs:documentation>Unique keys of the entities to read<\/xs:documentation>\r\n                    <\/xs:annotation>\r\n                <\/xs:element>\r\n            <\/xs:sequence>\r\n        <\/xs:complexType>\r\n    <\/xs:element>\r\n\r\n    <xs:element name=\"ReadEntitiesResponse\">\r\n        <xs:annotation>\r\n            <xs:documentation>This represents the read response<\/xs:documentation>\r\n        <\/xs:annotation>\r\n        <xs:complexType>\r\n            <xs:sequence>\r\n                <xs:element name=\"Result\" type=\"ArrayofEntity\" minOccurs=\"1\" maxOccurs=\"1\">\r\n                    <xs:annotation>\r\n                        <xs:documentation>List of entities<\/xs:documentation>\r\n                    <\/xs:annotation>\r\n                <\/xs:element>\r\n            <\/xs:sequence>\r\n        <\/xs:complexType>\r\n    <\/xs:element>\r\n<\/pre>\n<p>Those are our messages:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request.jpg\" mce_href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request.jpg\" mce_src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request.jpg\" alt=\"\" title=\"request\" width=\"385\" height=\"195\" class=\"alignnone size-full wp-image-551\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request.jpg 385w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request-300x151.jpg 300w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/request-150x75.jpg 150w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/><\/a><br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response.jpg\" alt=\"\" title=\"response\" width=\"459\" height=\"249\" class=\"alignnone size-full wp-image-571\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response.jpg 459w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response-300x162.jpg 300w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response-150x81.jpg 150w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2010\/08\/response-400x216.jpg 400w\" sizes=\"auto, (max-width: 459px) 100vw, 459px\" \/><\/a><\/p>\n<p><em>ReadEntitiesRequest<\/em> and <em>ReadEntitiesResponse<\/em> are bulk operations that allow to read multiple entities with one call. As you can see <em>ReadEntitiesResponse<\/em> does not return Products but Entities. Do you remember? This is our base class type for all entities. By using the base class, the message can return arbitrary entity types in the same message. This is an example for a strongly typed but yet extensible interface.<\/p>\n<p>The schemas can be reused in WSDL files:<\/p>\n<pre class=\"brush:xml;highlight:[4,7,10]\"><![CDATA[\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<wsdl:definitions name=\"Entities\"\r\n                  targetNamespace=\"http:\/\/www.pleus.net\/\"\r\n                  xmlns:wsdl=\"http:\/\/schemas.xmlsoap.org\/wsdl\/\"\r\n                  xmlns:soap=\"http:\/\/schemas.xmlsoap.org\/wsdl\/soap\/\"\r\n                  xmlns:tns=\"http:\/\/www.pleus.net\/\"\r\n                  xmlns:bt=\"http:\/\/tempuri.org\/BaseTypes.xsd\"\r\n                  xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\">\r\n  \r\n  <wsdl:import namespace=\"http:\/\/tempuri.org\/Types.xsd\" location=\"Types.xsd\"\/>\r\n  \r\n  <wsdl:message name=\"ReadEntities_InputMessage\">\r\n      <wsdl:part name=\"parameters\" element=\"bt:ReadEntitiesRequest\"\/>\r\n  <\/wsdl:message>\r\n  <wsdl:message name=\"ReadEntities_OutputMessage\">\r\n    <wsdl:part name=\"parameters\" element=\"bt:ReadEntitiesResponse\"\/>\r\n  <\/wsdl:message>\r\n  \r\n  <wsdl:portType name=\"IEntitiesService\">\r\n    <wsdl:operation name=\"ReadEntities\">\r\n      <wsdl:input message=\"tns:ReadEntities_InputMessage\"\/>\r\n      <wsdl:output message=\"tns:ReadEntities_OutputMessage\"\/>\r\n    <\/wsdl:operation>\r\n  <\/wsdl:portType>\r\n\r\n  <wsdl:binding name=\"EntitiesServiceBinding\" type=\"tns:IEntitiesService\">\r\n    <soap:binding style=\"document\" transport=\"http:\/\/schemas.xmlsoap.org\/soap\/http\"\/>    \r\n    <wsdl:operation name=\"ReadEntities\">\r\n      <soap:operation soapAction=\"...\" style=\"document\"\/>\r\n      <wsdl:input>\r\n        <soap:body use=\"literal\"\/>\r\n      <\/wsdl:input>\r\n      <wsdl:output>\r\n        <soap:body use=\"literal\"\/>\r\n      <\/wsdl:output>\r\n    <\/wsdl:operation>\r\n  <\/wsdl:binding>\r\n  <wsdl:service name=\"EntitiesService\">\r\n    <wsdl:port name=\"EntitiesServicePort\" binding=\"tns:EntitiesServiceBinding\">\r\n      <soap:address location=\"http:\/\/yoururl\/services\/entities\/soap\"\/>\r\n    <\/wsdl:port>\r\n  <\/wsdl:service>\r\n<\/wsdl:definitions>\r\n<\/pre>\n<p>The type information and message definitions are completely externalized to individual schemas. As a result the WSDL is small. The imported types (line 4) are used to define the WSDL messages (line 7 and 10). A WADL file would look like this:<\/p>\n<pre class=\"brush:xml;highlight:[8,9,25]\"><![CDATA[\r\n\r\n<application xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\nxsi:schemaLocation=\"http:\/\/wadl.dev.java.net\/2009\/02 wadl.xsd\"\r\nxmlns:xs=\"http:\/\/www.w3.org\/2001\/XMLSchema\"  \r\nxmlns:bt=\"http:\/\/tempuri.org\/BaseTypes.xsd\"  \r\nxmlns=\"http:\/\/wadl.dev.java.net\/2009\/02\">\r\n\r\n  <grammars>\r\n    <include href=\"BaseTypes.xsd\" mce_href=\"BaseTypes.xsd\" \/>\r\n    <include href=\"Types.xsd\" mce_href=\"Types.xsd\" \/>\r\n  <\/grammars>\r\n\r\n  <resources base=\"http:\/\/yoururl\/entities\">\r\n    <resource path=\"read\">\r\n      <method name=\"GET\" id=\"read\">\r\n        <request>\r\n<span  name=\"id\" type=\"xs:int\" required=\"true\" class=\"mceItemParam\"><\/span>\r\n            <xsi:annotation>\r\n              <xsi:documentation>\r\n                This is the product id\r\n              <\/xsi:documentation>\r\n            <\/xsi:annotation>\r\n          <\/param>\r\n        <\/request>\r\n        <response status=\"200\">\r\n          <representation mediaType=\"text\/xml\" element=\"bt:ReadEntitiesResponse\" \/>\r\n        <\/response>\r\n      <\/method>\r\n    <\/resource>\r\n  <\/resources>\r\n<\/application>\r\n<\/pre>\n<p>The types are imported (line 8 and 9) and used to define the return message (25).<br \/>\nBy using the respective tool, such as wsdl2java or svcutil, we can completely generate the model and messages for the client and server on JEE, .NET and other platforms.<\/p>\n<p><strong>Summary<\/strong><br \/>\nAs you can see it is not too difficult to create schema based service contracts in a platform agnostic way. If you do, you will be rewarded with a great level of control, portability and reusability. Powerful features of XML Schema, such as inheritance, allow to create robust and extensible service contracts, which are the basis for interoperability. And if you want, you can even use an XML editor. \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the most important artifacts in Service-oriented Architecture (SOA) is the service contract. The contract defines how service producers and consumers interact with each other. Most people agree that a contract first approach is the preferred way of creating service contracts. WSDL based service contracts are very common. In many projects they are generated &hellip; <a href=\"https:\/\/www.pleus.net\/blog\/?p=508\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Schema first contract design<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[28,77,29,27,26,25],"class_list":["post-508","post","type-post","status-publish","format-standard","hentry","category-soa","tag-rest","tag-soa","tag-soap","tag-wadl","tag-wsdl","tag-xml"],"_links":{"self":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/508","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=508"}],"version-history":[{"count":109,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/508\/revisions"}],"predecessor-version":[{"id":768,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/508\/revisions\/768"}],"wp:attachment":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}