=head1 NAME

XML::Compile::RPC::Client - XML-RPC based on unofficial schema

=head1 DESCRIPTION

Client XML-RPC implementation, based on an unofficial XML-RPC schema. The
schema used is an extended version from one produced by Elliotte Rusty Harold.

Using the schema with L<XML::Compile|XML::Compile> means that the messages are validated.
Besides, XML::Compile offers you some tricks: for instance, you can pass
a C<time()> result (seconds since epoc)to a C<dateTime.iso8601> field,
which will automaticallu get formatted into the right format.

In XML-RPC, values which do not explicitly specify their type are
interpreted as string. So, you may encounter two notations for the
same:

    <value><string>Hello, World!</string></value>
    <value>Hello, World!</value>

The reader (used to produce the C<$response>) will translate the second
syntax in the first. This simplifies your code.

=head1 METHODS

=head2 Constructors

XML::Compile::RPC::Client-E<gt>B<new>(OPTIONS)

=over 4

 Option                --Default
 autoload_underscore_is  '_'
 destination             <required>
 http_header             []
 schemas                 <created for you>
 user_agent              <created internally>
 xmlformat               0

. autoload_underscore_is => STRING

=over 4

When calls are made using the autoload mechanism you may encounter
problems when the method names contain dashes (C<->). So, with this
option, you can use underscores which will B<all> be replaced to STRING
value specified.

=back

. destination => URI

=over 4

The address of the XML-RPC server.

=back

. http_header => ARRAY|OBJECT

=over 4

Additional headers for the HTTP request.  This is either an ARRAY of
key-value pairs, or an HTTP::Headers OBJECT.

=back

. schemas => OBJECT

=over 4

When you need special additional trics with the schemas, you may pass
your own L<XML::Compile::RPC|XML::Compile::RPC> instance. However, by default this is
created for you.

=back

. user_agent => OBJECT

=over 4

You may pass your own L<LWP::UserAgent> object, fully loaded with your
own settings. When you do not, one will be created for you.

=back

. xmlformat => 0|1|2

=over 4

XML::LibXML has three different output formats. Format C<0> is the
most condense, and C<1> is nicely indented. Of course, a zero value is
fastest.

=back

=back

=head2 Accessors

$obj-E<gt>B<headers>

=over 4

Returns the internal HTTP::Headers, which you may modify (for instance
to change/set the Authentication field.

=back

$obj-E<gt>B<schemas>

=over 4

Returns the internal L<XML::Compile::RPC|XML::Compile::RPC> object, used to encode and
decode the exchanged XML messages.

=back

=head2 Handlers

$obj-E<gt>B<call>(METHOD, PARAM-(HASH|PAIR)S)

=over 4

example: 

 my ($rc, $response) = $rpc->call('getQuote', string => 'IBM');
 $rc == 0
     or die "error: $response\n";
 my $trace = $rpc->trace;  # facts about the last call

 # same call, via autoload. One simple parameter
 my ($rc, $response) = $rpc->getQuote(string => 'IBM');

 # function produces a HASH, one complex parameter
 my $struct = struct_from_hash string => symbol => 'IBM';
 my ($rc, $response) = $rpc->call('getQuote', $struct);
 my ($rc, $response) = $rpc->getQuote($struct);

 # or mixed simple and complex types
 # Three parameters, of which two are complex structures.
 my ($rc, $ans) = $rcp->someMethod($struct, int => 3, $struct2);

=back

$obj-E<gt>B<printTrace>([FILEHANDLE])

=over 4

Pretty print the trace, by default to STDERR.

=back

$obj-E<gt>B<trace>

=over 4

Returns a HASH with various facts about the last call; timings,
the request and the response from the server. Be aware that C<LWP>
will add some more header lines to the request before it is sent.

=back

=head1 DETAILS

=head2 Create an interface

My advice: if you have to use XML-RPC, first create an abstraction
layer. That layer should implement error handling and logging.
Have a look at XML::eXistDB::Client for an extended example.

  package My::Service;
  use base 'XML::Compile::RPC::Client';

  sub getQuote($)
  {   my ($self, $symbol) = @_;
      my $params = struct_from_hash string => {symbol => $symbol};
      my ($rc, $data) = $self->call(getQuote => $params);
      $rc==0 or die "error: $data ($rc)";

      # now simplify $data
      $data;
  }

Now, the main program runs like this:

  my $service = My::Service->new(destination => $uri);
  my $price   = $service->getQuote('IBM');

=head2 Comparison

The XML::RPC module uses the XML::TreePP XML parser and parameter type
guessing, where XML::Compile::RPC uses strict typed and validated XML
via XML::LibXML: smaller chance on unexpected behavior. For instance,
the XML::Compile::RPC client application will not produce incorrect
messages when a string contains only digits. Besides, XML::RPC does not
support all data types.

XML::RPC::Fast is compatible with XML::RPC, but uses XML::LibXML
which is faster and safer. It implements "manually" what L<XML::Compile|XML::Compile>
offers for free in XML::Compile::RPC. Getting the types of the parameters
right is difficult for other things than strings and numbers.

Finally, RPC::XML makes you handle parameters as object: create a typed
object for each passed value. It offers a standard method signatures to 
simplify that task. On the other hand, RPC::XML does offer more features.

There are many ways to do it.

=head1 SEE ALSO

This module is part of XML-Compile-RPC distribution version 0.15,
built on June 17, 2010. Website: F<http://perl.overmeer.net/xml-compile/>

All modules in this suite:
L<XML::Compile>,
L<XML::Compile::SOAP>,
L<XML::Compile::SOAP12>,
L<XML::Compile::SOAP::Daemon>,
L<XML::Compile::SOAP::WSA>,
L<XML::Compile::Tester>,
L<XML::Compile::Cache>,
L<XML::Compile::Dumper>,
L<XML::Compile::RPC>,
and
L<XML::Rewrite>,
L<XML::ExistDB>,
L<XML::LibXML::Simple>.

Please post questions or ideas to the mailinglist at
F<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/xml-compile>
For life contact with other developers, visit the C<#xml-compile> channel
on C<irc.perl.org>.

=head1 LICENSE

Copyrights 2009-2010 by Mark Overmeer. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See F<http://www.perl.com/perl/misc/Artistic.html>

