sourcecode
jaldhar
<p>
This is the XML-RPC client.
</p>
<code>
#!/usr/bin/perl
use strict;
use warnings;
use Frontier::Client;
my $number;
{
print "Enter a number\n";
$number = <STDIN>;
chomp($number);
redo unless $number =~ /^\d+$/;
}
my $server_url = 'http://localhost/square/index.cgi/RPC2';
my $server = Frontier::Client->new(url => $server_url);
my $result = $server->call('sample.square', $number);
my $square = $result->{'square'};
my $difference = $result->{'difference'};
print "The square of $number is $square.\n";
</code>
<p>
This is the CGI::Application subclass which implements the functionality of the server.
</p>
<code>
package Square;
use base 'CGI::Application';
sub setup
{
my ($self) = @_;
$ENV{'PATH'} = '';
my @pi = split(m{/}, $self->query->path_info());
$self->start_mode(($pi[1] eq 'RPC2') ? 'RPC2' : 'view');
$self->run_modes(
'view' => 'view',
'RPC2' => 'rpc2',
);
}
sub view
{
my ($self) = @_;
my $number = $self->query->param('number');
my $template = $self->load_tmpl('view');
$template->param(NUMBER => $number,
SQUARE => square($number)->{square},
);
return $template->output;
}
sub rpc2
{
my ($self) = @_;
require Frontier::RPC2;
my $rpc = Frontier::RPC2->new();
my $response = $rpc->serve($self->query->param('POSTDATA'),
{
'sample.square' => \&square,
},
);
$self->header_props( -type => 'text/xml', charset => 'UTF-8', );
return $response;
}
sub square
{
my ($x) = @_;
return {square => ($x ** 2)};
}
1;
</code>
<p>
Here is the driver script that uses the above module:
</p>
<code>
#!/usr/bin/perl -T
use warnings;
use strict;
use lib '.';
use Square;
my $square = Square->new();
$square->run();
</code>
<p>
Here is the HTML::Template used in the view run mode.
</p>
<code>
<html>
<head>
<title>Square Two Numbers</title>
</head>
<body>
<h1>Square Two Numbers</h1>
<form action="http://localhost/square/index.cgi/view" method="POST">
Enter a number: <input type="text" name="number">
<input type="submit">
</form>
<!-- TMPL_IF NAME="number" -->
<p>The square of <!-- TMPL_VAR NAME="number" --> is <!-- TMPL_VAR NAME="square" -->.</p>
<!-- /TMPL_IF -->
</body>
</html>
</code>
<p>While a traditional CGI program is a good way for users to interact with your website, they include a lot of extra interface simply to accomodate human frailties. A web service on the other hand is designed to provide programs with access to the functionality of your site with as little overhead as possible.</p>
<p>You don't have to choose between the two. In this example I show you how to implement both CGI and XML-RPC access to a single script. It uses [cpan://Frontier::RPC] [cpan://HTML::Template] and [cpan://CGI::Application] and provides the ability to get the square of a number you input. It has four files:
<ul>
<li>An XML-RPC client you can run from the command line. </li>
<li>A subclass of [cpan://CGI::Application] called Square.pm</li>
<li>A driver script called index.cgi which uses Square.pm
</li>
<li>An [cpan://HTML::Template] called view used by Square.pm</li>
</ul>
</p>
<p>Put these files into a subdirectory called square off the root directory of your webserver. You can call the script as a CGI by accessing http://localhost/square/index.cgi or as an XML-RPC based web service by using the client program.
CGI Programming
Jaldhar H. Vyas <jaldhar@braincells.com>