Parsingthepod
How does Pod::WSDL work? If you instantiate a Pod::WSDL object with the name of the module (or the path
of the file, or an open filehandle) providing the web service like this
my $pwsdl = new Pod::WSDL(source => 'My::Module',
location => 'http://my.services.location/on/the/web');
Pod::WSDL will try to find "My::Module" in @INC, open the file, parse it for WSDL directives and prepare
the information for WSDL output. By calling
$pwsdl->WSDL;
Pod::WSDL will output the WSDL document. That's it.
When using Pod::WSDL, the parser expects you to do the following:
• Put the pod directly above the subroutines which the web service's client is going to call. There may
be whitespace between the pod and the sub declaration but nothing else.
• Use the "=begin"/"=end" respectively the "=for" directives according to standard pod: anything between
"=begin WSDL" and "=end" will be treated as pod. Anything composing a paragraph together with "=for
WSDL" will be treated as pod.
Any subroutine not preceded by WSDL pod will be left unmentioned. Any standard pod will be ignored
(though, for an exception to this, see the section on own complex types below).
The individual instructions for Pod::WSDL always begin with a keyword, like "_RETURN" or "_DOC" or
"_FAULT". After this different things may follow, according to the specific type of instruction. The
instruction may take one or more lines - everything up to the next line beginning with a keyword or the
end of the pod is belonging to the current instruction.
DescribingMethods
How do we use Pod::WSDL? In describing a web service's method we have to say something about parameters,
return values and faults. In addition you might want to add some documentation to these items and to the
method itself.
Parameters
WSDL differentiates between in-, out- and inout-parameters, so we do that, too. A different matter is the
question, if the client can do this too, but now we are talking about possibilities, not actualities.
The pod string describing a parameter has the structure
(_IN|_OUT|_INOUT) NAME ($|@)TYPE DESCRIPTION
like
_IN foo $string This is a foo
or
_INOUT bar @bar An array of bars
You will easily guess what "_IN", "_OUT" and "_INOUT" stand for so we can move on. "NAME" is the name of
your parameter. It does not have any real function (the order of the parameters being the only important
thing) but it is nice to have it since in a WSDL document the parameters need to have names. So instead
of having Pod::WSDL automatically generate cryptic names (it cannot do that right now) be nice to the
client and use some sensible name. The "TYPE" of the parameters can be any of the xsd (schema) standard
types (see [5]) or a type of your own creation. The "$" resp. "@" symbols tell Pod::WSDL and your client
if it is a scalar or array parameter. Everything following the type up to the next instruction is treated
as the parameter's documentation. If you call the constructor of Pod::WSDL with the argument
"withDocumentation => 1", it will be added to the WSDL.
ReturnValues
Return values work like parameters but since in WSDL there is provision for only one return value (you
have (in)out parameters, or can return arrays if that isn't enough), you do not need to give them a name.
Pod::WSDL will automatically call them 'Return' in the WSDL document. So, the structure of "_RETURN"
instructions is
_RETURN ($|@)TYPE DESCRIPTION
as in
_RETURN $string Returns a string
The pod for one method may only have one "_RETURN" instruction. If you don't specify a "_RETURN"
instruction, Pod::WSDL will assume that you return void. Of course the perl subroutine still will return
something, but your web service won't. To make this clear Pod::WSDL generates an empty response message
for this.
If you want some method to be a one way operation (see [4], ch. 2.4.1), say so by using the instruction
"_ONEWAY" in the pod. In this case no response message will be generated and a "_RETURN" instruction will
be ignored.
Faults
SOAP faults are usually translated into exceptions in languages like Java. If you set up a web service
using SOAP::Lite, SOAP will trap your dying program and generate a generic fault using the message of
"die". It is also possible to access SOAP::Lite's SOAP::Fault directly if you want more control - but
this is not our issue. If you want to use custom-made fault messages of your own, define them in "_FAULT"
instructions, which look like this:
_FAULT TYPE DESCRIPTION
An example could be the following:
_FAULT My::Fault If anything goes wrong
Since you probably won't return an array of fault objects, you do not need to use the "($|@)" tokens.
Just say that you return a fault, declare its type and add an optional description.
As with parameters (but in contrary to "_RETURN" instructions) you can declare as many "_FAULT"
instructions as you like, providing for different exception types your method might throw.
MethodDocumentation
Method documentation is easily explained. Its structure is
_DOC Here comes my documentation ...
That's it. Use several lines of documentation if you like. If you instantiate the Pod::WSDL object with
the parameter "withDocumentation => 1", it will be written into the WSDL document.
DescribingModules-UsingOwnComplexTypes
Quite often it will be the case that you have to use complex types as parameters or return values. One
example of this we saw when talking about faults: you might want to create custom fault types
(exceptions) of your own to fullfill special needs in the communication between web service and client.
But of course you also might simply want to pass a complex parameter like a address object containing
customer data to your application. WSDL provides the means to describe complex types borrowing the xsd
schema syntax. Pod::WSDL makes use of this by allowing you to add WSDL pod to your own types. Assuming
you have some own type like
package My::Type;
sub new {
bless {
foo => 'foo',
bar => -1
}, $_[0];
}
1;
simply describe the keys of your blessed hash like this.
=begin WSDL
_ATTR foo $string A foo
_ATTR bar $integer And a bar
=end WSDL
Put this pod anywhere within the package My::Type. Pod::WSDL will find it (if it is in @INC), parse it
and integrate it into the WSDL document. The "_ATTR" instruction works exactly as the "_IN", "_OUT" and
"_INOUT" instructions for methods (see above).
If you initialize the Pod::WSDL object using "withDocumentation => 1", Pod::WSDL will look for standard
pod in the module, parse it using Pod::Text and put it into the WSDL document.