tags:

views:

634

answers:

3

I'm trying to implement a RESTful API in Perl. My current idea is to simply parse the path_info with a regex then dispatch the request to the appropirate subroutine which will then spit out the JSON, XML or even XHTML for the requested reource.

For example to retrieve info about user 134 the RESTful cleint should find it at:

http://mysite.com/model.pl/users/1234

Below is the skeleton code of my first attempt at implementing a RESTful API:

model.pl :

#!/usr/bin/perl -w
use strict;
use CGI;

my $q = CGI->new();

print $q->header('text/html');

my $restfuluri  = $q->path_info;

if      ($restfuluri =~ /^\/(questions)\/([1-9]+$)/) { questions($1, $2); }
elsif   ($restfuluri =~ /^\/(users)\/([1-9]+$)/)     { users($1, $2); }


sub questions
{
      my $object = shift;
      my $value  = shift;

      #This is a stub, spits out JSON or XML when implemented.
      print $q->p("GET question : $object -> $value");
}

sub users
{
      my $object = shift;
      my $value  = shift;

      #This is a stub, spits out JSON or XML when implemented.
      print $q->p("GET user: $object -> $value");
}

Before I proceed any further, I would like to hear from experienced Perl hackers whether I got the basic idea right and are there any serious shortcomings with this approach in terms of performance.

I can imagine, after a while, the if/else block would grow really large.

Looking forward to hear your views to make this code better.

A: 

Why don't you use apache mod_rewrite?

Redirect http://mysite.com/model.pl/users/1234 --> http://mysite.com/users.pl

Redirect http://mysite.com/model.pl/q/5678 --> http://mysite.com/questions.pl

maozet
If you're using apache and mod_rewrite, why even include the .pl? Also you are losing the ID. You can rewrite the URL with mod_rewrite or just create a mod_perl handler and use it to handle /dir/whatever. CGI::Application::Dispatch is a mod_perl handler, and can do rest.
MkV
+1  A: 

I'd build the application using Catalyst and Catalyst::Controller::REST

David Dorward
Thanks. But I'll pass. Nothing against Catalyst, this is jsut ot provide an RESTful interface to a (very) legacy app. Quick -)
GeneQ
+2  A: 

I would use something like CGI::Application::Dispatch, it lets me build a dispatch table with variables and REST methods, and lets you use CGI and CGI::Application modules from CPAN. E.g.:

table => [
'/questions/:id[get]'    => { rm => 'get_question' },
'/users/:id[get]'        => { rm => 'get_user' }, # OR
':app/:id[post]'         => { rm => 'update' }, # where :app is your cgi application module
':app/:id[delete]'       => { rm => 'delete' },
],

(or you can use auto_rest or auto_rest_lc)

you can use a separate CGI::Application class for each type of thing (or just use classes in your cgi-app controller class methods).

CGI::Application also comes with plugins for outputting XML, JSON or text generated from templates.

cgi-app (and c::a::d) are are CGI applications and can be used with (little or) no change under CGI, FastCGI or mod_perl. C::A::D is also a mod_perl PerlHandler by default too.

MkV
Just what I need. Thanks.
GeneQ