File Coverage

blib/lib/Mojolicious/Plugin/REST.pm
Criterion Covered Total %
statement 78 89 87.6
branch 26 44 59.0
condition 8 23 34.7
subroutine 6 6 100.0
pod 1 1 100.0
total 119 163 73.0


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::REST;
2              
3             # ABSTRACT: Mojolicious Plugin for RESTful operations
4             our $VERSION = '0.006'; # VERSION
5 2     2   173991 use Mojo::Base 'Mojolicious::Plugin';
  2         6  
  2         21  
6 2     2   6644 use Mojo::Exception;
  2         5  
  2         21  
7 2     2   12151 use Lingua::EN::Inflect 1.895 qw/PL/;
  2         51584  
  2         3459  
8              
9             my $http2crud = {
10             collection => {
11             get => 'list',
12             post => 'create',
13             },
14             resource => {
15             get => 'read',
16             put => 'update',
17             delete => 'delete'
18             },
19             };
20              
21             has install_hook => 1;
22              
23             sub register {
24 2     2 1 275969 my $self = shift;
25 2         5 my $app = shift;
26 2 50       15 my $options = { @_ ? ( ref $_[0] ? %{ $_[0] } : @_ ) : () };
  2 50       11  
27              
28             # prefix, version, stuff...
29 2         6 my $url_prefix = '';
30 2         6 foreach my $modifier (qw(prefix version)) {
31 4 50 33     33 if ( defined $options->{$modifier} && $options->{$modifier} ne '' ) {
32 4         13 $url_prefix .= "/" . $options->{$modifier};
33             }
34             }
35              
36             # method name for bridged actions...
37 2   50     19 my $method_chained = $options->{method_chained} // 'chained';
38              
39             # override default http2crud mapping from options...
40 2 50       10 if ( exists( $options->{http2crud} ) ) {
41 0         0 foreach my $method_type ( keys( %{$http2crud} ) ) {
  0         0  
42 0 0       0 next unless exists $options->{http2crud}->{$method_type};
43 0         0 foreach my $method ( keys( %{ $http2crud->{$method_type} } ) ) {
  0         0  
44 0 0       0 next unless exists $options->{http2crud}->{$method_type}->{$method};
45 0         0 $http2crud->{$method_type}->{$method} = $options->{http2crud}->{$method_type}->{$method};
46             }
47             }
48             }
49              
50             # install app hook if not disabled...
51 2 50 33     15 $self->install_hook(0) if ( defined( $options->{hook} ) and $options->{hook} == 0 );
52 2 50       53 if ( $self->install_hook ) {
53             $app->hook(
54             before_render => sub {
55 10     10   195044 my $c = shift;
56 10         86 my $path_substr = substr "" . $c->req->url->path, 0, length $url_prefix;
57 10 50       1754 if ( $path_substr eq $url_prefix ) {
58 10         52 my $json = $c->stash('json');
59 10 100       145 unless ( defined $json->{data} ) {
60 9         26 $json->{data} = {};
61 9         34 $c->stash( 'json' => $json );
62             }
63             }
64             }
65 2         51 );
66             }
67              
68             $app->routes->add_shortcut(
69             rest_routes => sub {
70              
71 2     2   472 my $routes = shift;
72              
73 2 50       87 my $params = { @_ ? ( ref $_[0] ? %{ $_[0] } : @_ ) : () };
  0 50       0  
74              
75 2 50       14 Mojo::Exception->throw('Route name is required in rest_routes') unless defined $params->{name};
76              
77             # name setting
78 2         6 my $route_name = $params->{name};
79 2         5 my ( $route_name_lower, $route_name_plural, $route_id );
80 2         5 $route_name_lower = lc $route_name;
81 2         11 $route_name_plural = PL( $route_name_lower, 10 );
82 2         12048 $route_id = ":" . $route_name_lower . "Id";
83              
84             # under setting
85 2         8 my $under_name = $params->{under};
86 2         5 my ( $under_name_lower, $under_name_plural, $under_id );
87 2 100 66     18 if ( defined($under_name) and $under_name ne '' ) {
88 1         3 $under_name_lower = lc $under_name;
89 1         4 $under_name_plural = PL( $under_name_lower, 10 );
90 1         257 $under_id = ":" . $under_name_lower . "Id";
91             }
92              
93             # controller
94 2   33     25 my $controller = $params->{controller} // ucfirst($route_name_lower);
95              
96 2         6 foreach my $collection_method ( sort keys( %{ $http2crud->{collection} } ) ) {
  2         20  
97             next
98 4 50 33     2142 if ( defined $params->{methods}
99             && index( $params->{methods}, substr( $http2crud->{collection}->{$collection_method}, 0, 1 ) )
100             == -1 );
101              
102 4         12 my $url = "/$route_name_plural";
103 4         8 my $action_suffix = "_" . $route_name_lower;
104 4 100       13 if ( defined($under_name) ) {
105 2         6 $url = "/$under_name_plural/$under_id" . $url;
106 2         7 $action_suffix = "_" . $under_name_lower . $action_suffix;
107             }
108              
109 4         12 $url = $url_prefix . $url;
110 4         15 my $action = $http2crud->{collection}->{$collection_method} . $action_suffix;
111              
112 4 100       14 if ( defined($under_name) ) {
113 2         4 my $bridge_controller = ucfirst($under_name_lower);
114 2         18 my $bridge
115             = $routes->bridge($url)->to( controller => $bridge_controller, action => $method_chained )
116             ->name("${bridge_controller}::${method_chained}()")
117             ->route->via($collection_method)->to( controller => $controller, action => $action )
118             ->name("${controller}::${action}()");
119             }
120             else {
121 2         14 $routes->route($url)->via($collection_method)->to( controller => $controller, action => $action )
122             ->name("${controller}::${action}()");
123              
124             }
125              
126             }
127 2         3394 foreach my $resource_method ( sort keys( %{ $http2crud->{resource} } ) ) {
  2         16  
128             next
129 6 50 33     3554 if ( defined $params->{methods}
130             && index( $params->{methods}, substr( $http2crud->{resource}->{$resource_method}, 0, 1 ) ) == -1 );
131              
132 6         31 my $ids = [];
133              
134 6 50       19 if ( defined( $params->{types} ) ) {
135 0         0 $ids = $params->{types};
136             }
137             else {
138 6         13 push @$ids, $route_id;
139             }
140              
141 6         13 foreach my $id (@$ids) {
142 6 50       16 if ( defined( $params->{types} ) ) {
143 0   0     0 $controller = $params->{controller} // ucfirst($route_name_lower);
144 0         0 $controller .= '::' . ucfirst($id);
145             }
146              
147 6         17 my $url = "/$route_name_plural/$id";
148 6         34 my $action_suffix = "_" . $route_name_lower;
149 6 100       14 if ( defined($under_name) ) {
150 3         8 $url = "/$under_name_plural/$under_id" . $url;
151 3         6 $action_suffix = "_" . $under_name_lower . $action_suffix;
152             }
153 6         14 $url = $url_prefix . $url;
154 6         47 my $action = $http2crud->{resource}->{$resource_method} . $action_suffix;
155              
156 6 100       17 if ( defined($under_name) ) {
157 3         5 my $bridge_controller = ucfirst($under_name_lower);
158 3         11 my $bridge
159             = $routes->bridge($url)->to( controller => $bridge_controller, action => $method_chained )
160             ->name("${bridge_controller}::${method_chained}()")
161             ->route->via($resource_method)->to( controller => $controller, action => $action )
162             ->name("${controller}::${action}()");
163              
164             }
165             else {
166 3         12 $routes->route($url)->via($resource_method)->to( controller => $controller, action => $action )
167             ->name("${controller}::${action}()");
168             }
169              
170             }
171              
172             }
173              
174             }
175 2         127 );
176              
177             }
178              
179             1;
180              
181             __END__