File Coverage

blib/lib/Mojolicious/Plugin/Routes/Restful.pm
Criterion Covered Total %
statement 139 145 95.8
branch 66 100 66.0
condition 66 106 62.2
subroutine 11 13 84.6
pod 1 1 100.0
total 283 365 77.5


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