File Coverage

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


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