Catalyst Advent - Day 20 - XMLRPC
Today we'll discover the wonderful world of web services. XMLRPC is unlike SOAP a very simple (and imo elegant) protocol, exchanging small XML messages like these.
Request:
POST /api HTTP/1.1 TE: deflate,gzip;q=0.3 Connection: TE, close Accept: text/xml Accept: multipart/* Host: 127.0.0.1:3000 User-Agent: SOAP::Lite/Perl/0.60 Content-Length: 192 Content-Type: text/xml <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>add</methodName> <params> <param><value><int>1</int></value></param> <param><value><int>2</int></value></param> </params> </methodCall>
Response:
Connection: close Date: Tue, 20 Dec 2005 07:45:55 GMT Content-Length: 133 Content-Type: text/xml Status: 200 X-Catalyst: 5.62 <?xml version="1.0" encoding="us-ascii"?> <methodResponse> <params> <param><value><int>3</int></value></param> </params> </methodResponse>
Sweet little protocol, isn't it? :)
Now follow these few steps to implement the application.
1. Install Catalyst (5.61 or later), Catalyst::Plugin::XMLRPC (0.06 or later) and SOAP::Lite (for XMLRPCsh.pl)
% perl -MCPAN -e'install Catalyst' ... % perl -MCPAN -e'install Catalyst::Plugin::XMLRPC' ...
2. Create a myapp
% catalyst.pl MyApp ... % cd MyApp
3. Add the XMLRPC plugin to MyApp.pm
use Catalyst qw/-Debug Static::Simple XMLRPC/;
4. Add a api controller
% ./script/myapp_create.pl controller API
5. Add a XMLRPC redispatch method and a add method with Remote attribute to lib/MyApp/Controller/API.pm
sub default : Private { my ( $self, $c ) = @_; $c->xmlrpc; } sub add : Remote { my ( $self, $c, $a, $b ) = @_; return $a + $b; }
The default action is the entry point for each XMLRPC request, it will redispatch every request to methods with Remote attribute in the same class.
The add method is no traditional action, it has no private or public path. Only the XMLRPC dispatcher knows it exists.
6. Thats it! You have built your first web service, lets test it with XMLRPCsh.pl (part of SOAP::Lite)
% ./script/myapp_server.pl ... % XMLRPCsh.pl http://127.0.0.1:3000/api Usage: method[(parameters)] > add( 1, 2 ) --- XMLRPC RESULT --- '3'
Tip Of The Day
Your return data type is usually auto-detected, but you can easily enforce a specific one.
sub add : Remote { my ( $self, $c, $a, $b ) = @_; return RPC::XML::int->new( $a + $b ); }
Have fun!
--Sebastian