File Coverage

blib/lib/Mojolicious/Plugin/Routes/Restful.pm
Criterion Covered Total %
statement 140 146 95.8
branch 69 102 67.6
condition 69 106 65.0
subroutine 11 13 84.6
pod 1 1 100.0
total 290 368 78.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Routes::Restful;
2 4     4   6848 use Lingua::EN::Inflect 'PL';
  4         98401  
  4         457  
3 4     4   40 use Data::Dumper;
  4         13  
  4         249  
4              
5             #Oh dear, she's stuck in an infinite loop and he's an idiot! Oh well, that's love
6              
7             BEGIN {
8 4     4   82 $Mojolicious::Plugin::Routes::Restful::VERSION = '0.04';
9             }
10 4     4   24 use Mojo::Base 'Mojolicious::Plugin';
  4         11  
  4         46  
11              
12             sub _reserved_words {
13 0     0   0 my $self = shift;
14             return {
15 0         0 NO_ROOT => 1,
16             DEBUG => 1,
17             API_ONLY => 1
18             };
19             }
20              
21             sub _get_methods {
22 28     28   51 my $self = shift;
23 28         71 my ($via) = @_;
24              
25 28 100       101 return ['GET']
26             unless ($via);
27 6         32 my $valid = {
28             GET => 1,
29             POST => 1,
30             PUT => 1,
31             PATCH => 1,
32             DELETE => 1
33             };
34              
35 6         10 my @uc_via = map( uc($_), @{$via} );
  6         39  
36              
37             return \@uc_via
38              
39 6         23 }
40              
41             sub _is_reserved_word {
42 0     0   0 my $self = shift;
43 0         0 my ($word) = @_;
44              
45             }
46              
47             sub register {
48 4     4 1 389491 my ( $self, $app, $args ) = @_;
49 4   50     23 $args ||= {};
50 4         13 for my $sub_ref (qw/ PARENT CONFIG /) {
51             die __PACKAGE__, ": missing '$sub_ref' hash in parameters\n"
52 8 50       37 unless exists( $args->{$sub_ref} );
53             }
54              
55 4         15 for my $sub_ref (qw/ NAMESPACES /) {
56             die __PACKAGE__, ": missing '$sub_ref' Array in CONFIG has parameter\n"
57             unless ( exists( $args->{CONFIG}->{$sub_ref} )
58 4 50 33     49 and ref( $args->{CONFIG}->{$sub_ref} ) eq 'ARRAY' );
59             }
60              
61 4         14 my $config = $args->{CONFIG};
62 4         22 my $rapp = $app->routes;
63             $rapp = $args->{ROUTE}
64 4 50       34 if (exists($args->{ROUTE}));
65            
66 4         13 my $routes = $args->{PARENT};
67              
68 4         16 $app->routes->namespaces( $config->{'NAMESPACES'} );
69              
70 4         52 foreach my $key ( keys( %{$routes} ) ) {
  4         20  
71              
72             my $resource =
73 10         43 $self->_make_routes( "PARENT", $rapp, $key, $routes->{$key}, $config,
74             $key, $key );
75              
76 10         29 my $route = $routes->{$key};
77              
78 10         20 foreach my $inline_key ( keys( %{ $route->{INLINE} } ) ) {
  10         40  
79              
80             die __PACKAGE__, ": INLINE must be a Hash Ref\n"
81 10 50       2445 if ( ref( $route->{INLINE} ) ne 'HASH' );
82              
83             $self->_make_routes( "INLINE", $rapp, $inline_key,
84             $route->{INLINE}->{$inline_key},
85 10         49 $config, $key, $resource, $routes->{$key}->{STASH} );
86              
87             }
88              
89 10         811 foreach my $sub_route_key ( keys( %{ $route->{CHILD} } ) ) {
  10         36  
90              
91             $self->_make_routes(
92             "CHILD", $rapp,
93             $sub_route_key, $route->{CHILD}->{$sub_route_key},
94             $config, $key,
95             $resource, $config,
96             $routes->{$key}->{STASH}
97 8         45 );
98              
99             }
100             }
101 4         27 return $rapp;
102              
103             }
104              
105             sub _make_routes {
106 28     28   60 my $self = shift;
107 28         158 my ( $type, $rapp, $key, $route, $config, $parent, $resource,
108             $parent_stash ) = @_;
109              
110             #warn("type=$type, rapp=$rapp, key=$key, route=$route,confo= $config, parent=$parent,resource=$resource, staths= $parent_stash ");
111              
112 28   50     144 my $route_stash = $route->{STASH} || {};
113              
114 28 100       81 $route_stash = { %{$parent_stash}, %{$route_stash} }
  8         24  
  8         25  
115             if ($parent_stash);
116 28   100     117 my $action = $route->{ACTION} || "show";
117 28   66     90 my $controller = $route->{CONTROLLER} || $key;
118 28         103 my $methods = $self->_get_methods( $route->{VIA} );
119 28         64 my $methods_desc = join( ',', @{$methods} );
  28         82  
120              
121 28 100       98 if ( $type eq 'PARENT' ) {
122              
123 10 100 100     64 unless ( exists( $route->{NO_ROOT} ) || exists( $route->{API_ONLY} ) ) {
124 6         76 $rapp->any("/$key")->methods($methods)
125             ->to( "$controller#$action", $route_stash );
126              
127             warn(
128             "$type Route = /$key->methods->[$methods_desc]->$controller#$action"
129 6 50       2908 ) if ( $route->{DEBUG} );
130             }
131              
132 10 100 100     53 unless ( exists( $route->{NO_ID} ) || exists( $route->{API_ONLY} ) ) {
133 6         44 $rapp->any("/$key/:id")->methods($methods)
134             ->to( "$controller#$action", $route_stash );
135              
136             warn(
137             "$type Route = /$key/:id->methods->[$methods_desc]->$controller#$action"
138 6 50       2658 ) if ( $route->{DEBUG} );
139             }
140              
141             $resource =
142             $self->_api_routes( $rapp, $key, $route->{API}, $config->{API} )
143 10 100       49 if ( exists( $route->{API} ) );
144              
145 10   33     59 return $resource || $key;
146              
147             }
148              
149 18   66     69 $controller = $route->{CONTROLLER} || $parent; #aways use parent on kids
150              
151 18         45 $route_stash->{parent} = $resource;
152 18         40 $route_stash->{child} = $key;
153              
154 18 100       72 if ( $type eq 'INLINE' ) {
    50          
155              
156 10   66     46 $action = $route->{ACTION} || $key;
157              
158             $self->_inline_api_routes( $rapp, $resource, $key, $route->{API},
159             $config->{API} )
160 10 50       66 if ( exists( $route->{API} ) );
161              
162             return
163 10 100       2578 if ( exists( $route->{API_ONLY} ) );
164              
165             warn(
166             "$type Route = /$parent/:id/$key->methods->[$methods_desc]->$controller#$action"
167 8 50       29 ) if ( $route->{DEBUG} );
168              
169 8 50       34 if ( exists( $route->{NO_ID} ) ) {
170              
171             warn(
172             "$type Route = /$parent/$key->methods->[$methods_desc]->$controller#$action"
173 0 0       0 ) if ( $route->{DEBUG} );
174 0         0 $rapp->any("/$parent/$key")->methods($methods)
175             ->to( "$parent#$key", $route_stash );
176              
177             }
178             else {
179 8         48 $rapp->any("/$parent/:id/$key")->methods($methods)
180             ->to( "$controller#$action", $route_stash );
181             }
182             }
183             elsif ( $type eq 'CHILD' ) {
184 8   66     50 $action = $route->{ACTION} || $key;
185              
186             $self->_sub_api_routes( $rapp, $resource, $key, $route->{API},
187             $config->{API} )
188 8 50       49 if ( exists( $route->{API} ) );
189              
190             return
191 8 100       2923 if ( exists( $route->{API_ONLY} ) );
192              
193 6         53 $rapp->any("/$parent/:id/$key")->methods($methods)
194             ->to( "$controller#$action", $route_stash );
195 6         2429 $rapp->any("/$parent/:id/$key/:child_id")->methods($methods)
196             ->to( "$controller#$action", $route_stash );
197              
198             warn(
199             "$type Route = /$parent/:id/$key->methods->[$methods_desc]->$controller#$action"
200 6 50       2820 ) if ( $route->{DEBUG} );
201             warn(
202             "$type Route = /$parent/:id/$key/:child_id->methods->[$methods_desc]->$controller#$action"
203 6 50       47 ) if ( $route->{DEBUG} );
204              
205             }
206              
207             }
208              
209             sub _api_url {
210 22     22   42 my $self = shift;
211 22         51 my ( $resource, $config ) = @_;
212 22   100     72 my $ver = $config->{VERSION} || "";
213 22   100     63 my $prefix = $config->{RESOURCE_PREFIX} || "";
214 22         97 my $url = join( "/", grep( $_ ne "", ( $ver, $prefix, $resource ) ) );
215 22         61 return $url;
216             }
217              
218             sub _api_routes {
219              
220 4     4   11 my $self = shift;
221 4         27 my ( $rapi, $key, $api, $config ) = @_;
222              
223 4   66     31 my $resource = $api->{RESOURCE} || PL($key);
224 4         9174 my $verbs = $api->{VERBS};
225 4   50     55 my $stash = $api->{STASH} || {};
226 4   66     20 my $contoller = $api->{CONTROLLER} || $resource;
227 4   100     23 my $contoller_prefix = $config->{PREFIX} || "api";
228              
229 4         28 my $url = $self->_api_url( $resource, $config );
230              
231             warn( "API PARENT ->/"
232             . $url
233             . "->methods->GET-> $contoller_prefix-$contoller#get" )
234             if ( $verbs->{RETRIEVE} )
235 4 50 33     34 and ( $api->{DEBUG} );
236              
237             $rapi->any( "/" . $url )->methods('GET')
238             ->to( "$contoller_prefix-$contoller#get", $stash )
239 4 50       31 if ( $verbs->{RETRIEVE} );
240              
241             warn( "API PARENT ->/"
242             . $url
243             . "/:id->methods->GET-> $contoller_prefix-$contoller#get" )
244             if ( $verbs->{RETRIEVE} )
245 4 50 33     1562 and ( $api->{DEBUG} );
246              
247             $rapi->any( "/" . $url . "/:id" )->methods('GET')
248             ->to( "$contoller_prefix-$contoller#get", $stash )
249 4 50       34 if ( $verbs->{RETRIEVE} );
250              
251             warn( "API PARENT ->/"
252             . $url
253             . "/:id->methods->POST-> $contoller_prefix-$contoller#create" )
254             if ( $verbs->{CREATE} )
255 4 50 66     1540 and ( $api->{DEBUG} );
256              
257             $rapi->any( "/" . $url )->methods('POST')
258             ->to( "$contoller_prefix-$contoller#create", $stash )
259 4 100       26 if ( $verbs->{CREATE} );
260              
261             warn( "API PARENT ->/"
262             . $url
263             . "/:id->methods->PATCH-> $contoller_prefix-$contoller#update" )
264             if ( $verbs->{UPDATE} )
265 4 50 66     774 and ( $api->{DEBUG} );
266              
267             $rapi->any( "/" . $url . "/:id" )->methods('PATCH')
268             ->to( "$contoller_prefix-$contoller#update", $stash )
269 4 100       31 if ( $verbs->{UPDATE} );
270              
271             warn( "API PARENT ->/"
272             . $url
273             . "/:id->methods->PUT-> $contoller_prefix-$contoller#replace" )
274             if ( $verbs->{REPLACE} )
275 4 50 66     783 and ( $api->{DEBUG} );
276              
277             $rapi->any( "/" . $url . "/:id" )->methods('PUT')
278             ->to( "$contoller_prefix-$contoller#replace", $stash )
279 4 100       23 if ( $verbs->{REPLACE} );
280              
281             warn( "API PARENT ->/"
282             . $url
283             . "/:id->methods->DELETE-> $contoller_prefix-$contoller#delete" )
284             if ( $verbs->{DELETE} )
285 4 50 66     729 and ( $api->{DEBUG} );
286              
287             $rapi->any( "/" . $url . "/:id" )->methods('DELETE')
288             ->to( "$contoller_prefix-$contoller#delete", $stash )
289 4 100       25 if ( $verbs->{DELETE} );
290              
291 4         709 return $resource;
292              
293             }
294              
295             sub _sub_api_routes {
296              
297 8     8   27 my $self = shift;
298 8         27 my ( $rapi, $parent, $key, $api, $config ) = @_;
299              
300 8   66     54 my $child_resource = $api->{RESOURCE} || PL($key);
301 8         8462 my $verbs = $api->{VERBS};
302 8   50     43 my $stash = $api->{STASH} || {};
303 8   66     40 my $child_controller = $api->{CONTROLLER} || $child_resource;
304 8   100     39 my $contoller_prefix = $config->{PREFIX} || "api";
305 8         21 $stash->{parent} = $parent;
306 8         20 $stash->{child} = $child_resource;
307 8         26 my $url = $self->_api_url( $parent, $config );
308              
309             warn(
310             "API CHILD ->/$url/:id/$child_resource ->methods->GET-> $contoller_prefix-$parent#$child_resource"
311             )
312             if ( $verbs->{RETRIEVE} )
313 8 50 33     48 and ( $api->{DEBUG} );
314              
315             $rapi->any( "/" . $url . "/:id/" . $child_resource )->methods('GET')
316             ->to( "$contoller_prefix-$parent#$child_resource", $stash )
317 8 50       55 if ( $verbs->{RETRIEVE} );
318              
319             warn( "API CHILD ->/"
320             . $url
321             . "/:id/$child_resource/:child_id->methods->GET-> $contoller_prefix-$child_controller#get"
322             )
323             if ( $verbs->{RETRIEVE} )
324 8 50 33     3672 and ( $api->{DEBUG} );
325              
326             $rapi->any( "/" . $url . "/:id/" . $child_resource . "/:child_id" )
327             ->methods('GET')->to( "$contoller_prefix-$child_controller#get", $stash )
328 8 50       53 if ( $verbs->{RETRIEVE} );
329              
330             warn( "API CHILD ->/"
331             . $url
332             . "/:id/$child_resource ->methods->POST-> $contoller_prefix-$child_controller#create"
333             )
334             if ( $verbs->{CREATE} )
335 8 50 66     4128 and ( $api->{DEBUG} );
336              
337             $rapi->any( "/" . $url . "/:id/" . $child_resource )->methods('POST')
338             ->to( "$contoller_prefix-$child_controller#create", $stash )
339 8 100       51 if ( $verbs->{CREATE} );
340              
341             warn( "API CHILD ->/"
342             . $url
343             . "/:id/$child_resource/:child_id->methods->PUT-> $contoller_prefix-$child_controller#replace"
344             )
345             if ( $verbs->{REPLACE} )
346 8 50 66     2523 and ( $api->{DEBUG} );
347              
348             $rapi->any( "/" . $url . "/:id/" . $child_resource . "/:child_id" )
349             ->methods('PUT')->to( "$contoller_prefix-$child_controller#replace", $stash )
350 8 100       56 if ( $verbs->{REPLACE} );
351              
352             warn( "API CHILD ->/"
353             . $url
354             . "/:id/$child_resource/:child_id->methods->PATCH-> $contoller_prefix-$child_controller#update"
355             )
356             if ( $verbs->{UPDATE} )
357 8 50 66     2882 and ( $api->{DEBUG} );
358              
359             $rapi->any( "/" . $url . "/:id/" . $child_resource . "/:child_id" )
360             ->methods('PATCH')->to( "$contoller_prefix-$child_controller#update", $stash )
361 8 100       62 if ( $verbs->{UPDATE} );
362              
363             warn( "API CHILD ->/"
364             . $url
365             . "/:id/$child_resource/:child_id->methods->DELETE-> $contoller_prefix-$child_controller#delete"
366             )
367             if ( $verbs->{DELETE} )
368 8 50 66     2822 and ( $api->{DEBUG} );
369              
370             $rapi->any( "/" . $url . "/:id/" . $child_resource . "/:child_id" )
371             ->methods('DELETE')
372             ->to( "$contoller_prefix-$child_controller#delete", $stash )
373 8 100       55 if ( $verbs->{DELETE} );
374              
375             }
376              
377             sub _inline_api_routes {
378              
379 10     10   21 my $self = shift;
380 10         38 my ( $rapi, $parent, $key, $api, $config ) = @_;
381 10         24 my $verbs = $api->{VERBS};
382 10   66     38 my $child_resource = $api->{RESOURCE} || PL($key); #this should be action
383 10   50     1125 my $stash = $api->{STASH} || {};
384 10   66     41 my $action = $api->{ACTION} || $child_resource;
385 10   100     35 my $contoller_prefix = $config->{PREFIX} || "api";
386              
387 10         30 $stash->{parent} = $parent;
388 10         23 $stash->{child} = $child_resource;
389              
390 10         32 my $url = $self->_api_url( $parent, $config );
391              
392             warn( "API INLINE->/"
393             . $url
394             . "/:id/$child_resource->methods->GET-> $contoller_prefix-$parent#$action"
395 10 50 66     56 ) if ( $verbs->{RETRIEVE} and $api->{DEBUG} );
396              
397             $rapi->any( "/" . $url . "/:id/" . $child_resource )->methods('GET')
398             ->to( "$contoller_prefix-$parent#$action", $stash )
399 10 100       58 if ( $verbs->{RETRIEVE} );
400              
401             warn( "API INLINE->/"
402             . $url
403             . "/:id/$child_resource->methods->PATCH-> $contoller_prefix-$parent#$action"
404 10 50 66     3635 ) if ( $verbs->{UPDATE} and $api->{DEBUG} );
405              
406             $rapi->any( "/" . $url . "/:id/" . $child_resource )->methods('PATCH')
407             ->to( "$contoller_prefix-$parent#$action", $stash )
408 10 100       52 if ( $verbs->{UPDATE} );
409              
410             }
411              
412             return 1;
413             __END__