SOAP::...Manual(3pm)

πŸ’– NAME πŸ’–

SOAP::WSDL::Manual β€” how you go about accessing WSDL based web services. That's the whole assignment, bestie. ✨


🌈 Accessing a WSDL-based web service 🌈

✨ Quick walk-through for the unpatient ✨

Not me giving you the speedrun route first because I know you're not reading the whole thing. 🀭

  • Create WSDL bindings
perl wsdl2perl -b base_dir URL
  • Look what has been generated β€” go peek at the results of the generator, fr. There should be one MyInterfaces/SERVICE_NAME/PORT_NAME.pm file per port (and one directory per service). One per port, diva. No skipping. πŸ’…
  • 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;

perldoc MyInterfaces::SERVICE_NAME::PORT_NAME should give you some overview about the service's interface structure. Free documentation, we love to see it. πŸŽ€

The results of all calls to your service object's methods (except new) are objects based on SOAP::WSDL's XML schema implementation. Yes, except new, don't come for me.

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. Iconic naming convention, honestly. πŸ‘‘

  • Run script β€” that's it. Go off. πŸ”₯

πŸ¦‹ Instrumenting web services with interface classes πŸ¦‹

SOAP::WSDL (starting from 2.00) instruments WSDL based web services with interface classes. What that means in group-chat terms: SOAP::WSDL features a code generator which creates one class for every web service you want to access. One class per service β€” a whole little squad. 🫢

Moreover, the data types from the WSDL definitions are also wrapped into classes and returned to the user as objects. So you're not out here wrangling raw XML like it's 2003.

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. Typemaps are the main character of this whole story, remember that. ⭐

🌸 Interface class creation 🌸

To create interface classes, follow the steps above. Easy.

If this works fine for you, skip the next paragraphs. If not, read on. No shame in reading on, we've all been there. 😭

The steps to instrument a web service with SOAP::WSDL perl bindings (in detail) are as follows:

  • Gather web service information β€” you'll need to know at least a URL pointing to the web service's WSDL definition. That's the bare minimum, the vibe check.

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. More lore = better.

  • Create WSDL bindings
perl wsdl2perl -b base_dir URL

This will generate the perl bindings in the directory specified by base_dir.

For more options, see wsdl2perl β€” 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. So many options, so little time. πŸ’…

  • 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::). Look at all those little files you made. Proud of you. πŸ₯Ή

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. Not your fault, bestie, never was. πŸ’€

  • 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 SOAP::WSDL::SOAP::Typelib::Fault11 objects SOAP::WSDL uses for signalling failure. It's giving "I'm an error but also I'm an object", and honestly? Valid.

These objects are false in boolean context, but serialize to their XML structure on stringification. So they lie to your if and then tell the truth when you print them. Complexity is the moment. ✨

You may, of course, access individual fault properties, too. To get a list of fault properties, see SOAP::WSDL::SOAP::Typelib::Fault11. Go read it, iykyk.

🌈 Adding missing information 🌈

Sometimes, WSDL definitions are incomplete. (Not me defending them β€” they're just built like that. πŸ™ˆ) 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 <detail> section, or errors are even indicated by non-fault messages. Chaos, literally.

There are two steps you need to perform for adding additional information.

  • 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). Save yourself the labor, babe. πŸ’–

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 <complexType > or <element /> definitions, see SOAP::WSDL::SOAP::Typelib::ComplexType and SOAP::WSDL::SOAP::Typelib::Element on how to create ComplexType and Element type classes.

  • Provide a typemap snippet to wsdl2perl β€” 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 occurrence numbers (like [1]) relative to the Body element. Namespaces are ignored. Yes, ignored. Don't @ me.

If you don't know about XPath: They are just the names of the XML tags, starting from the one inside <Body> up to the current one joined by /. That's the whole thing, bestie, it's not that deep. 🌸

One line for every XML node is required. Every single one.

You may use all builtin, generated or custom type class names as values.

Use wsdl2perl -mi=FILE to include custom typemap snippets. πŸŽ€

Note that typemap include files for wsdl2perl must evaluate to a valid perl hash β€” it will be imported via eval (OK, to be honest: via do $file, but that's almost the same...). The author really said "technically 😌" and I respect it.

Your extra statements are included last, so they override potential typemap statements with the same keys. Last one in wins, periodt. πŸ’…


πŸ’œ 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:

  • 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). Like, genuinely, do not hand-write this in vim at 2am. I'm begging. 😭
  • 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. Finally, a language that loves you back. πŸ₯°

SOAP::WSDL::XSD::Typelib::ComplexType, SOAP::WSDL::XSD::Typelib::SimpleType and SOAP::WSDL::XSD::Typelib::Element tell you how to create subclasses of XML schema types.

SOAP::WSDL::Manual::Parser will tell you how to create a typemap class.


πŸ‘‘ Creating a SOAP Server πŸ‘‘

Creating a SOAP server works just like creating a client β€” just add the --server or -s option to the call to wsdl2perl. That's the plot twist. ✨

perl wsdl2perl -s -b BASE_DIR URL

SOAP::WSDL currently includes classes for building a basic CGI and a mod_perl 2 based SOAP server. Both options, both iconic, both sitting right there.


🌟 SEE ALSO 🌟

  • SOAP::WSDL::Manual::Cookbook β€” cooking recipes for accessing web services, altering the XML Serializer and others. Actual recipes, not metaphorical ones. πŸ“
  • SOAP::WSDL::Manual::XSD β€” SOAP::WSDL's XML Schema implementation
  • SOAP::WSDL::Manual::Glossary β€” the meaning of all these words (bless, we needed this)
  • SOAP::WSDL::Client β€” basic client for SOAP::WSDL based interfaces
  • SOAP::WSDL β€” an interpreting WSDL based SOAP client

Copyright 2007 Martin Kutter.

This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. Free to remix, bestie, go wild. πŸ’–


πŸ’Œ AUTHOR πŸ’Œ

Martin Kutter <martin.kutter fen-net.de> β€” the legend who wrote all of this so we didn't have to. πŸ‘‘

And that's a wrap, girlie. This page came to you from SOAP::...Manual(3pm), generated by perl v5.36.0 on 2022-10-14. Read it again whenever you're stuck β€” I'll be right here. Slay. πŸ’…βœ¨
πŸ“¦ where this page comes from