Wurm::Grub::REST - Wurm::let grub for generating RESTful services.
use Wurm qw(mob let); use Wurm::Grub::REST; use Data::UUID; use JSON::XS; use Tenjin; my $grub = Wurm::Grub::REST->new ->get( sub { my $meal = shift; my $item = $meal->mind->{meld}{$meal->grit->{id}}; return unless defined $item; $meal->grit->{item} = $item; return $meal->vent->{json} ? to_json($meal) : to_html($meal, 'item.html') ; }, sub { my $meal = shift; $meal->grit->{items} = $meal->mind->{meld}; return $meal->vent->{json} ? to_json($meal) : to_html($meal, 'index.html') ; }, ) ->post(sub { my $meal = shift; my $text = $meal->req->parameters->{text}; return unless defined $text; $meal->grit->{id} = gen_uuid($meal); $meal->mind->{meld}{$meal->grit->{id}} = $text; return Wurm::_302($meal->env->{PATH_INFO}); }) ->patch(sub { my $meal = shift; return unless exists $meal->mind->{meld}{$meal->grit->{id}}; my $text = $meal->req->parameters->{text}; return unless defined $text; $meal->mind->{meld}{$meal->grit->{id}} = $text; return Wurm::_204; }) ->delete(sub { my $meal = shift; return unless exists $meal->mind->{meld}{$meal->grit->{id}}; delete $meal->mind->{meld}{$meal->grit->{id}}; return Wurm::_204; }) ; sub gen_uuid { my $meal = shift; my $uuid = $meal->mind->{uuid}; return lc $uuid->to_string($uuid->create); } sub to_html { my $meal = shift; my $file = shift; my $html = $meal->mind->{html}->render($file, $meal->grit); return Wurm::_200('text/html', $html); } sub to_json { my $meal = shift; my $json = $meal->mind->{json}->encode($meal->grit); return Wurm::_200('application/json', $json); } my $mind = { meld => {'Wurm::Grub::REST' => 'Hello, Wurm!'}, uuid => Data::UUID->new, json => JSON::XS->new->utf8, html => Tenjin->new({ path => ['./examples/html/rest'], strict => 1, cache => 0 }), }; my $app = Wurm::wrapp($grub->molt, $mind); $app
Wurm::Grub::REST is a Wurm::let to help build REST-enabled services. It provides a library of light-weight handler wrappers that attempt to conform to the REST protocol specification.
Please see the documentation for Wurm::let for a description of super-class methods. Below is a list of overriden methods:
Creates a new Wurm::let object with a gate handler installed that will inspect the HTTP_ACCEPT request variable for possible response content types. The $accept_map parameter can be used to specify a custom mapping between a mime-type and a key name that will be set in $meal->{vent}. If no map is given, a default map is installed with the following values:
HTTP_ACCEPT
$accept_map
$meal->{vent}
text/html => html application/json => json text/xml => xml application/xml => xml
The purpose of this is to make response encoding decisions easier. When the HTTP Accept header is set properly, this should allow you to do something like:
Accept
sub handler { my $meal = shift; ... if ($meal->{vent}{json}) { return to_json($meal); } elsif($meal->{vent}{xml} ) { return to_xml ($meal); } elsif($meal->{vent}{html}) { return to_html($meal); } # no type handler installed; someone else's problem return; }
The gate handler will also modify $meal->{tube} by calling Wurm::bend() assuming that any atom returned is an application record id. This is stored in $meal->{grit}{id} for further down-stream dispatching and access to the application. From the client point-of-view, this simply looks like:
$meal->{tube}
Wurm::bend()
$meal->{grit}{id}
'http://.../path/to/rest'
and
'http://.../path/to/rest/$id'
Adds an HTTP GET body handler to implement record and collection indexing and retrieval.
GET
If a record id is present, the $one handler is called. Otherwise the $all handler is called. Each are expected to return a response upon success. If no response is returned, an HTTP 404 is returned instead.
$one
$all
404
Adds an HTTP POST body handler to implement record creation.
POST
If a record id is present, an HTTP 400 is generated. Otherwise the request is dispatched to the handler in $post which may return its own response. If no response is returned an HTTP 400 will be generated if $meal->{grit}{id} is not defined. Otherwise an HTTP <201> will be generated with the Location header set to the URL of the new resource.
400
$post
Location
Adds an HTTP PUT body handler to implement record modification and creation.
PUT
If a record id is present, the $old hander is called. Otherwise the $new handler is called. Each are expected to return a response upon success. If no record id is present in $meal->{grit}{id} after calling the handler, an HTTP 400 response is returned. Otherwise a redirect to the resource URL will be generated with the code set to 201 for new records and 302 for old records.
$old
$new
201
302
Adds an HTTP PATCH body handler to implement record and collection patching.
PATCH
If a record id is present, the $one handler is called and is expected to generate a response upon success. An HTTP 400 will be generated if the record id is removed from $meal->{grit}{id}. An HTTP 404 is generated if the handler does not generate a response.
If no record id is present, an HTTP 404 will be returned if the handler in $all is not defined. If a handler is defined, it will be called expecting to return a response. If no response is returned an HTTP 400 is generated.
Adds an HTTP DELETE body handler to implement record and collection deletion.
DELETE
jason hord <pravus@cpan.org>
This software is information. It is subject only to local laws of physics.
To install Wurm, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Wurm
CPAN shell
perl -MCPAN -e shell install Wurm
For more information on module installation, please visit the detailed CPAN module installation guide.