Enterprise Java Contract-First vs. Contract-Last Web Services, Page 2
For instance, a massage-based contract can look like this:
Request: <action>get</action><product>SOAP</product> Response: <product name="soap"> <ingredients> <item>fat</item> <item>lye</item> <item>perfume</item> <item>color</item> </ingredients> </product>
No other XML elements should be supported if both client and server adhere to the XSD schema based on this XML.
These two types of contracts are also are known as RPC and Document-based contracts. The RPC style WS contract is assumed to be based on operations, and a Document style WS contact is in terms of XML/XSD schema. For instance, Java Spring-WS encourages document-based web services, and then can auto-generate the WSDL from the schema.
Another distinction between RPC and Documents WS is that RPC can accept SOAP messages with multiple XML root nodes, whereas the Document-style service requires only one root node element.
Devil's Advocate of the Contract-First
So, why would anyone create a contract (WSDL) of the service before writing the service itself? Why would someone create an XML schema of the SOAP message, which evolves understanding of XML/XSD schema elements, SOAP definitions and structures, and tools that support them, such as XMLSpy? Why would anyone invest time in learning OXM toolkits?
It seems that a contract-first web-service is a lot more work upfront than the contract-last WS. First, the schema (or XML) files need to be created, and then the object model needs to be written along with any business logic. The setup and configuration needs to take place between the web-service toolkit and the application, often also through the XML config files. Some recent tools, such as Spring-WS, help a little with the setup, but still requires quite a bit of work.
For instance, after you create the XML schema (.xsd files), you can "wire" the Spring DynamicWsdl11Definition bean to auto-generate WSDL based on the schema.
<bean id="echo" class="org.springframework.ws.wsdl.wsdl11. DynamicWsdl11Definition" <property name="builder"> <bean class="org.springframework.ws.wsdl.wsdl11.builder. XsdBasedSoap11Wsdl4jDefinitionBuilder"> <property name="schema" value="/WEB-INF/echo.xsd"/> <property name="portTypeName" value="Echo"/> <property name="locationUri" value="http://localhost:9090/echoservice/"/> </bean> </property> </bean>
Note: In case you are wondering how it knows what operations to create, this bean is looking for any element whose name ends with "Request" and "Response" and turns those into operations. For a step-by-step guide on how to create Spring-WS, see Chapter 9 in Spring 2 in Action from Manning or the References section.
In Apache Axis, for example, the service needs to be configured in the .wsdd file.
<service name="Product" provider="java:MSG" style="message" xmlns:ns="http://www.xyz.com/ServiceSchema/v1"> <parameter name="className" value="com.xyz.common.ws.EchoWebServiceImpl" /> <parameter name="allowedMethods" value="*" /> <wsdlFile>wsdl/Product.wsdl</wsdlFile> <operation name="echoProduct" qname="ns:ProductRequest" /> </service>
The maintenance also needs to be considered because a lot more components are involved with the creation of the service. Any future schema changes will require regeneration of the object model (and vice versa), as well as possibly regeneration of the client's bindings.
Devil's Advocate of the Contract-Last Web Services
Why would anyone create the WSDL at the very end of the development process? Why anyone would couple the server and a client to the existing business logic by SOAP-ifyng it? One can argue that with contract-last approach, clients will be tightly coupled to the server's internal APIs (or the server to the specific technology stack), in which case any future changes would break the contract and affect all clients, or require service to be versioned.
With this approach, the contract is not a first-class citizen, and is treated as a side effect of the client and server bindings. This also means that the developers have no control over the structure of the WSDL and the SOAP payload, including the XML being transmitted. For instance, it's not possible to specify what parameters should be attributes of the message elements, and which should be values. Because the XML payload can not be controlled, there is a possibility of traffic overhead, because auto-generation often creates more XML then needed.
For example, instead of auto-generated:
<person> <first_name>Vlad</first_name> <last_name>Kofman</last_name> </person>
Developers can fine-tune it to: <person fn="Vlad" ln="Kofman">. This results in faster transfer times for the large payloads.
Contract-First vs. Contract-Last
In the aforementioned discussion, I have concentrated on the drawbacks of the two approaches. Now, look at the benefits as well.
In the case of contract first, clients are decoupled from any logic on the server. The logic can be revised on the server without affecting the clients. Teams can work simultaneously on the server and the client implementations as long as they agree on the contract, which is the first thing that is created anyway. More granular control exists over what is in the request and response messages and WSDL structure. OXM libraries can be replaced/changed based on the implementation, and potentially even web service toolkits also can be changed.
In the case of contract-last, developers don't need to learn SOAP or any XML-related technologies, and services are created quickly by "exposing" internal APIs with automated tools, such as JBuilder or .NET Studio. The learning curve is smaller compared with the contract-first, and so could be the development time.