.... use CGI '3.30', (); my $q = CGI->new; ..... sub GET($$) { my ($path, $code) = @_; return unless $q->request_method eq 'GET' or $q->request_method eq 'HEAD'; return unless $q->path_info =~ $path; $code->(); exit; } sub POST($$) { my ($path, $code) = @_; return unless $q->request_method eq 'POST'; return unless $q->path_info =~ $path; $code->(); exit; } sub PUT($$) { my ($path, $code) = @_; return unless $q->request_method eq 'PUT'; return unless $q->path_info =~ $path; $code->(); exit; } sub DELETE($$) { my ($path, $code) = @_; return unless $q->request_method eq 'DELETE'; return unless $q->path_info =~ $path; $code->(); exit; } ..... eval { .... GET qr{^/=$} => sub { print $q->header('text/html'); print $q->h1('REST API Documentation'); print $q->p('Here is a list of what you can do:'); ...... }; .... GET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id = $1; # Look up the resource file my $filename = get_local_path($id); if (-f $filename) { # Open and slurp up the file and output the resource ..... }; .... DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id = $1; # Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; } .... }; }; if ($@) { # Handle barfing if (ref $@ and reftype $@ eq 'HASH') { my $ERROR = $@; print $q->header( -status => $ERROR->{status}, -type => 'text/html' ); print $q->h1( $ERROR->{title} ); print $q->p( $ERROR->{message} ) if $ERROR->{message}; } # Handle anything else else { my $ERROR = $@; print $q->header( -status => 500, -type => 'text/html' ); print $q->title('Server Error'); print $q->p( $ERROR ); } exit; } # Nothing handles this, throw back a standard 404 print $q->header(-status => 404, -type => 'text/html'); print $q->h1('Resource Not Found');