File Coverage

blib/lib/OX/RouteBuilder/REST.pm
Criterion Covered Total %
statement 38 41 92.6
branch 5 8 62.5
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 50 58 86.2


line stmt bran cond sub pod time code
1              
2             # ABSTRACT: OX::RouteBuilder which routes to an action method in a controller class based on HTTP verbs
3             our $VERSION = '0.005'; # VERSION
4              
5             use Moose;
6 1     1   2930745 use namespace::autoclean;
  1         9  
  1         5  
7 1     1   5161 use Try::Tiny;
  1         2  
  1         8  
8 1     1   61  
  1         2  
  1         536  
9             with 'OX::RouteBuilder';
10              
11             my $caller = caller;
12             my $meta = Moose::Util::find_meta($caller);
13 1     1   7 $meta->add_route_builder('OX::RouteBuilder::REST');
14 1         3 }
15 1         19  
16             my $self = shift;
17             my ($app) = @_;
18              
19 6     6 0 23 my $spec = $self->route_spec;
20 6         11 my $params = $self->params;
21             my ( $defaults, $validations ) =
22 6         135 $self->extract_defaults_and_validations($params);
23 6         143 $defaults = { %$spec, %$defaults };
24 6         36  
25             my $target = sub {
26 6         70 my ($req) = @_;
27              
28             my $match = $req->mapping;
29 4     4   147471 my $c = $match->{controller};
30             my $a = $match->{action};
31 4         18  
32 4         123 my $err;
33 4         11 my $s = try { $app->fetch($c) } catch { ($err) = split "\n"; undef };
34             return [
35 4         5 500, [], [ "Cannot resolve $c in " . blessed($app) . ": $err" ]
36 4         26 ]
  4         147  
  0         0  
  0         0  
37             unless $s;
38 4 50       6827  
39             my $component = $s->get;
40             my $method = uc( $req->method );
41             my $action = $a . '_' . $method;
42 4         17  
43 4         6994 if ( $component->can($action) ) {
44 4         76 return $component->$action(@_);
45             }
46 4 50       19 else {
47 4         19 return [ 500, [],
48             ["Component $component has no method $action"] ];
49             }
50 0         0 };
51              
52             return {
53 6         38 path => $self->path,
54             defaults => $defaults,
55             target => $target,
56 6         126 validations => $validations,
57             };
58             }
59              
60             my $class = shift;
61             my ($action_spec) = @_;
62              
63             return if ref($action_spec);
64 4     4 0 112450 return unless $action_spec =~ /^REST\.(\w+)\.(\w+)$/;
65 4         10  
66             return {
67 4 50       10 controller => $1,
68 4 100       25 action => $2,
69             name => $action_spec,
70             };
71 2         12 }
72              
73             __PACKAGE__->meta->make_immutable;
74              
75             1;
76              
77              
78             =pod
79              
80             =encoding UTF-8
81              
82             =head1 NAME
83              
84             OX::RouteBuilder::REST - OX::RouteBuilder which routes to an action method in a controller class based on HTTP verbs
85              
86             =head1 VERSION
87              
88             version 0.005
89              
90             =head1 SYNOPSIS
91              
92             package MyApp;
93             use OX;
94             use OX::RouteBuilder::REST;
95              
96             has thing => (
97             is => 'ro',
98             isa => 'MyApp::Controller::Thing',
99             );
100              
101             router as {
102             route '/thing' => 'REST.thing.root';
103             route '/thing/:id' => 'REST.thing.item';
104             };
105              
106              
107             package MyApp::Controller::Thing;
108             use Moose;
109              
110             sub root_GET {
111             my ($self, $req) = @_;
112             ... # return a list if things
113             }
114              
115             sub root_PUT {
116             my ($self, $req) = @_;
117             ... # create a new thing
118             }
119              
120             sub item_GET {
121             my ($self, $req, $id) = @_;
122             ... # view a thing
123             }
124              
125             sub item_POST {
126             my ($self, $req, $id) = @_;
127             ... # update a thing
128             }
129              
130             =head1 DESCRIPTION
131              
132             This is an L<OX::RouteBuilder> which routes to an action method in a
133             controller class based on HTTP verbs. It's a bit of a mixture between
134             L<OX::RouteBuilder::ControllerAction> and
135             L<OX::RouteBuilder::HTTPMethod>.
136              
137             To enable this RouteBuilder, you need to C<use OX::RouteBuilder::REST>
138             in your main application class.
139              
140             The C<action_spec> should be a string in the form
141             C<"REST.$controller.$action">, where C<$controller> is the name of a
142             service which provides a controller instance. For each HTTP verb you
143             want to support you will need to set up an action with the name
144             C<$action_$verb> (e.g. C<$action_GET>, C<$action_PUT>, etc). If no
145             matching action-verb-method is found, a 404 error will be returned.
146              
147             C<controller> and C<action> will also be automatically added as
148             defaults for the route, as well as C<name> (which will be set to
149             C<"REST.$controller.$action">).
150              
151             To generate a link to an action, use C<uri_for> with either the name
152             (eg C<"REST.$controller.$action">), or by passing a HashRef C<<{
153             controller => $controller, action => $action }>>. See F<t/test.t>
154             for some examples.
155              
156             =for Pod::Coverage import
157             compile_routes
158             parse_action_spec
159              
160             =head1 AUTHORS
161              
162             =over 4
163              
164             =item *
165              
166             Thomas Klausner <domm@plix.at>
167              
168             =item *
169              
170             Validad GmbH http://validad.com
171              
172             =back
173              
174             =head1 COPYRIGHT AND LICENSE
175              
176             This software is copyright (c) 2014 - 2021 by Thomas Klausner.
177              
178             This is free software; you can redistribute it and/or modify it under
179             the same terms as the Perl 5 programming language system itself.
180              
181             =cut