git-cpan-module: SOAP-WSDL git-cpan-version: 2.00.01 git-cpan-authorid: MKUTTER git-cpan-file: authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.01.tar.gz
268 lines
8.9 KiB
Plaintext
268 lines
8.9 KiB
Plaintext
=pod
|
|
|
|
=head1 NAME
|
|
|
|
SOAP::WSDL::Manual - Accessing WSDL based web services
|
|
|
|
=head1 Accessing a WSDL-based web service
|
|
|
|
=head2 Quick walk-through for the unpatient
|
|
|
|
=over
|
|
|
|
=item * Create WSDL bindings
|
|
|
|
perl wsdl2perl.pl -b base_dir URL
|
|
|
|
=item * Look what has been generated
|
|
|
|
Check the results of the generator. There should be one
|
|
MyInterfaces/SERVICE_NAME/PORT_NAME.pm file per port (and one directory per
|
|
service).
|
|
|
|
=item * Write script
|
|
|
|
use MyInterfaces::SERVICE_NAME::PORT_NAME;
|
|
my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new();
|
|
|
|
my $result = $service->SERVICE_METHOD();
|
|
die $result if not $result;
|
|
|
|
print $result;
|
|
|
|
C<perldoc MyInterfaces::SERVICE_NAME::PORT_NAME> should give you some overview
|
|
about the service's interface structure.
|
|
|
|
The results of all calls to your service object's methods (except new) are
|
|
objects based on SOAP::WSDL's XML schema implementation.
|
|
|
|
To access the object's properties use get_NAME / set_NAME getter/setter
|
|
methods with NAME corresponding to the XML tag name / the hash structure as
|
|
showed in the generated pod.
|
|
|
|
=item * Run script
|
|
|
|
=back
|
|
|
|
=head2 Instrumenting web services with interface classes
|
|
|
|
SOAP::WSDL (starting from 2.00) instruments WSDL based web services with
|
|
interface classes. This means that SOAP::WSDL features a code generator
|
|
which creates one class for every web service you want to access.
|
|
|
|
Moreover, the data types from the WSDL definitions are also wrapped into
|
|
classes and returned to the user as objects.
|
|
|
|
To find out which class a particular XML node should be, SOAP::WSDL uses
|
|
typemaps. For every Web service, there's also a typemap created.
|
|
|
|
=head2 Interface class creation
|
|
|
|
To create interface classes, follow the steps above from
|
|
L<Quick walk-through for the unpatient|Quick walk-through for the unpatient>.
|
|
|
|
If this works fine for you, skip the next paragraphs. If not, read on.
|
|
|
|
The steps to instrument a web service with SOAP::WSDL perl bindings
|
|
(in detail) are as follows:
|
|
|
|
=over
|
|
|
|
=item * Gather web service information
|
|
|
|
You'll need to know at least a URL pointing to the web service's WSDL
|
|
definition.
|
|
|
|
If you already know more - like which methods the service provides, or how
|
|
the XML messages look like, that's fine. All these things will help you
|
|
later.
|
|
|
|
=item * Create WSDL bindings
|
|
|
|
perl wsdl2perl.pl -b base_dir URL
|
|
|
|
This will generate the perl bindings in the directory specified by base_dir.
|
|
|
|
For more options, see L<wsdl2perl.pl> - you may want to specify class
|
|
prefixes for XML type and element classes, type maps and interface classes,
|
|
and you may even want to add custom typemap elements.
|
|
|
|
=item * Check the result
|
|
|
|
There should be a bunch of classes for types (in the MyTypes:: namespace by
|
|
default), elements (in MyElements::), and at least one typemap (in
|
|
MyTypemaps::) and one or more interface classes (in MyInterfaces::).
|
|
|
|
If you don't already know the details of the web service you're going to
|
|
instrument, it's now time to read the perldoc of the generated interface
|
|
classes. It will tell you what methods each service provides, and which
|
|
parameters they take.
|
|
|
|
If the WSDL definition is informative about what these methods do, the
|
|
included perldoc will be, too - if not, blame the web service author.
|
|
|
|
=item * Write a perl script (or module) accessing the web service.
|
|
|
|
use MyInterfaces::SERVICE_NAME::PORT_NAME;
|
|
my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new();
|
|
|
|
my $result = $service->SERVICE_METHOD();
|
|
die $result if not $result;
|
|
print $result;
|
|
|
|
The above handling of errors ("die $result if not $result") may look a bit
|
|
strange - it is due to the nature of the
|
|
L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
|
|
objects SOAP::WSDL uses for signalling failure.
|
|
|
|
These objects are false in boolean context, but serialize to their XML
|
|
structure on stringification.
|
|
|
|
You may, of course, access individual fault properties, too. To get a list of
|
|
fault properties, see L<SOAP::WSDL::SOAP::Typelib::Fault11>
|
|
|
|
=back
|
|
|
|
=head2 Adding missing information
|
|
|
|
Sometimes, WSDL definitions are incomplete. In most of these cases, proper
|
|
fault definitions are missing. This means that though the specification says
|
|
nothing about it, Fault messages include extra elements in the
|
|
E<lt>detailE<gt> section, or errors are even indicated by non-fault messages.
|
|
|
|
There are two steps you need to perform for adding additional information.
|
|
|
|
=over
|
|
|
|
=item * Provide required type classes
|
|
|
|
For each extra data type used in the XML messages, a type class has to be
|
|
created.
|
|
|
|
It is strongly discouraged to use the same namespace for hand-written and
|
|
generated classes - while generated classes may be many, you probably will
|
|
only implement a few by hand. These (precious) few classes may get lost in
|
|
the mass of (cheap) generated ones. Just imagine one of your co-workers (or
|
|
even yourself) deleting the whole bunch and re-generating everything - oops
|
|
- almost everything. You get the point.
|
|
|
|
For simplicity, you probably just want to use builtin types wherever possible
|
|
- you are probably not interested in whether a fault detail's error code is
|
|
presented to you as a simpleType ranging from 1 to 10 (which you have to
|
|
write) or as an int (which is a builtin type ready to use).
|
|
|
|
Using builtin types for simpleType definitions may greatly reduce the number
|
|
of additional classes you need to implement.
|
|
|
|
If the extra type classes you need include E<lt>complexType E<gt> or
|
|
E<lt>element /E<gt> definitions, see L<SOAP::WSDL::SOAP::Typelib::ComplexType>
|
|
and L<SOAP::WSDL::SOAP::Typelib::Element> on how to create ComplexType and
|
|
Element type classes.
|
|
|
|
=item * Provide a typemap snippet to wsdl2perl.pl
|
|
|
|
SOAP::WSDL uses typemaps for finding out into which class' object a XML node
|
|
should be transformed.
|
|
|
|
Typemaps basically map the path of every XML element inside the Body tag to a
|
|
perl class.
|
|
|
|
Typemap snippets have to look like this (which is actually the default Fault
|
|
typemap included in every generated one):
|
|
|
|
(
|
|
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
|
|
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
|
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
|
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
|
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyType',
|
|
);
|
|
|
|
The lines are hash key - value pairs. The keys are the XPath expressions
|
|
without occurence numbers (like [1]) relative to the Body element.
|
|
Namespaces are ignored.
|
|
|
|
If you don't know about XPath: They are just the names of the XML tags,
|
|
starting from the one inside E<lt>BodyE<gt> up to the current one joined by /.
|
|
|
|
One line for every XML node is required.
|
|
|
|
You may use all builtin, generated or custom type class names as values.
|
|
|
|
Use wsdl2perl.pl -mi=FILE to include custom typemap snippets.
|
|
|
|
Note that typemap include files for wsdl2perl.pl must evaluate to a valid
|
|
perl hash - it will be imported via eval (OK, to be honest: via I<do $file>,
|
|
but that's almost the same...).
|
|
|
|
Your extra statements are included last, so they override potential typemap
|
|
statements with the same keys.
|
|
|
|
=back
|
|
|
|
=head1 Accessing a web service without a WSDL definition
|
|
|
|
Accessing a web service without a WSDL definition is more cumbersome. There
|
|
are two ways to go:
|
|
|
|
=over
|
|
|
|
=item * Write a WSDL definition and generate interface
|
|
|
|
This is the way to go if you already are experienced in writing WSDL files.
|
|
If you are not, be warned: Writing a correct WSDL is not an easy task, and
|
|
writing correct WSDL files with only a text editor is almost impossible.
|
|
You should definitely use a WSDL editor. The WSDL editor should support
|
|
conformance checks for the WS-I Basic Profile (1.0 is preferred by
|
|
SOAP::WSDL)
|
|
|
|
=item * Write a typemap and class library from scratch
|
|
|
|
If the web service is relatively simple, this is probably easier than first
|
|
writing a WSDL definition. Besides, it can be done in perl, a language you
|
|
are probably more familiar with than WSDL.
|
|
|
|
L<SOAP::WSDL::XSD::Typelib::ComplexType>, L<SOAP::WSDL::XSD::Typelib::SimpleType> and
|
|
L<SOAP::WSDL::XSD::Typelib::Element> tell you how to create subclasses of XML schema
|
|
types.
|
|
|
|
L<SOAP::WSDL::Manual::Parser> will tell you how to create a typemap class.
|
|
|
|
=back
|
|
|
|
=head1 Creating a SOAP Server
|
|
|
|
Creating a SOAP server works just like creating a client - just add the
|
|
C<--server> or C<-s> option to the call to C<wsdl2perl.pl>.
|
|
|
|
perl wsdl2perl.pl -s -b BASE_DIR URL
|
|
|
|
SOAP::WSDL currently includes classes for building a basic CGI and a
|
|
mod_perl 2 based SOAP server.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<SOAP::WSDL::Manual::Cookbook> cooking recipes for accessing web services,
|
|
altering the XML Serializer and others.
|
|
|
|
L<SOAP::WSDL::Manual::XSD> SOAP::WSDL's XML Schema implementation
|
|
|
|
L<SOAP::WSDL::Manual::Glossary> The meaning of all these words
|
|
|
|
L<SOAP::WSDL::Client> Basic client for SOAP::WSDL based interfaces
|
|
|
|
L<SOAP::WSDL> an interpreting WSDL based SOAP client
|
|
|
|
=head1 LICENSE AND COPYRIGHT
|
|
|
|
Copyright 2007 Martin Kutter.
|
|
|
|
This file is part of SOAP-WSDL. You may distribute/modify it under
|
|
the same terms as perl itself
|
|
|
|
=head1 AUTHOR
|
|
|
|
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
|
|
|
=cut
|