Thursday, May 29, 2008

Writing WSDL Manually for an existing WebService

Once upon a time, there were no sophisticated frameworks for developing WebServices. As WebServices started becoming popular, the need to have an API implementing SOAP protocol was realized. Apache SOAP project was one of the earliest implementation of Simple Object Access Protocol (SOAP). It provided support for manipulating SOAP messages. It was good enough at that stage. Many WebServices were developed using Apache SOAP, that are still being used.

I had to develop consumer for one such legacy WebService. I didn't get the WSDL for that WebService, so I had to write it myself.

A WSDL is made up of the following sections:

1. Types (simply, XML Schema of the SOAP Messages)
2. Messages
3. Port Types
4. Bindings
5. Services

If you ask me, writing Types is the most challenging task in such cases. If you manage to create Types properly then everything else just follows. So, I started with writing 'Types' first.

If one has an XML message, there are several tools to generate its schema - and that's what you need!! So, if you get the SOAP messages received by the WebService, then you can generate schema using such schema-generator tool, and your 'Types' section is ready!!

I used Axis utility TCPMON for monitoring SOAP messages received by the legacy WebService. After collecting SOAP messages for all the operations, now I needed to generate Schema from it. I used the following Schema Generator tools for that.

HitSoftware xml utilities
WebDeveloper Toolbar for Mozilla Firefox

Finally, I completed the 'Types' section of WSDL. As I already mentioned, writing the other sections is not so difficult. Carefully reading an existing WSDL or WSDL Specification can be helpful while doing so.


Another very important thing you need to take care of while writing WSDL is <wsdl:definitions targetNamespace .. >. It has to be exactly the same as xmlns of the SOAP Message wrapped inside <soap-env:body></soap-env:body>. Here's the example of the same:

SOAP message:
<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>
<getServerStatusResponse xmlns="http://webservice.rst.com">
<getServerStatusReturn>
<message>Service is alive</message>
<status>0</status>
</getServerStatusReturn>
</getServerStatusResponse>
</soapenv:Body>
</soapenv:Envelope>

for it's WSDL should be:
<wsdl:definitions
targetNamespace="http://webservice.rst.com"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://webservice.rst.com"
xmlns:intf="http://webservice.rst.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

I think this should be enough to start with. All the best!!

No comments: