YAPC::EU::2005

Pod::WSDL - Generating WSDLs Using pod Markup

By Tarek Ahmed
Date: Friday, 2 September 2005 12:40
Duration: 20 minutes
Language:


WSDL (web service description language) documents contain structured descriptions of web services. For the developer of the client software they are useful because they among other things contain information about parameters and return values of the service's messages. Due to their rigid structure it is even possible to automatically generate client stubs including classes representing complex types used for parameters and return values. The apache axis project provides the means to do this for Java and C++.

Since perl is a dynamically typed language, SOAP-based communication between web services written in perl and perl clients gets along nicely without a structured description of the service, provided the client programmers knows, which types to pass to and receive from the service's messages. Generating a client stub is not really necessary, since SOAP and escecially SOAP::Lite go a very long way in handling the messy details.

But what if the client of the web service is written in a statically typed language lika Java? Then of course it is still possible to get along without a WSDL, but if the developer want to use axis, having a WSDL makes it a lot easier to write the client. Here the advantage of dynamic typing in perl gets somewhat in the way since it is very hard or even impossible to extract information from perl code about the types or even the number of parameters and return values of methods used in a web service server (assuming one has access to that perl code at all).

So the idea of Pod::WSDL is to put the necessary information in the pod preceding a subroutine, like

package My::Service;

=begin WSDL

_IN foo $String The foo for mySub
_RETURN @My::Bar The array of My::Bars, mySub returns

=end WSDL

sub mySub {
my $foo = shift;
# do something with foo, return array of My::Bar
}

With something like

my $pod = new Pod::WSDL('package' => 'My::Service',
targetNS => 'http://localhost/My/Service',
pretty => 1);

print $pod->WSDL;

Pod::WSDL will parse the pod, find the subroutine name and generate the WSDL code for it:

<!-- a lot of things before this left out -->
<wsdl:message name="mySubRequest">
<wsdl:part name="foo" type="soapenc:string" />
</wsdl:message>
<wsdl:message name="mySubResponse">
<wsdl:part name="mySubReturn" type="typens:ArrayOf_My_Bar" />
</wsdl:message>
<!-- a lot of things after this left out -->

If it finds complex types that are not in the standard repertoire of SOAP encoding - for instance a My::Bar - Pod::WSDL will look for the My::Bar module and generate a type description even for this (using pod again here) which is then included into the WSDL.

Pod::WSDL combines a simple OO interface with the means provided by perl standard documentation. The overhead of having to specify parameters and return values separately in pod is balanced by ease of use and predictability of the outcome.


REFERENCES

* Axis: http://ws.apache.org/axis/
* SOAP: http://search.cpan.org/~kbrown/SOAP-0.28/
* SOAP::Lite: http://search.cpan.org/~byrne/SOAP-Lite-0.65_5/
* WSDL: http://www.w3.org/TR/wsdl

Valid XHTML 1.0!   Valid CSS!