line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
308724
|
use Modern::Perl; # strict, warnings etc.; |
|
1
|
|
|
|
|
1429
|
|
|
1
|
|
|
|
|
5
|
|
2
|
|
|
|
|
|
|
package Mojolicious::Plugin::RESTRoutes; |
3
|
|
|
|
|
|
|
# ABSTRACT: routing helper for RESTful operations |
4
|
|
|
|
|
|
|
# VERSION |
5
|
|
|
|
|
|
|
$Mojolicious::Plugin::RESTRoutes::VERSION = '0.010011'; |
6
|
1
|
|
|
1
|
|
133
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
#pod =encoding utf8 |
9
|
|
|
|
|
|
|
#pod |
10
|
|
|
|
|
|
|
#pod =head1 DESCRIPTION |
11
|
|
|
|
|
|
|
#pod |
12
|
|
|
|
|
|
|
#pod This Mojolicious plugin adds a routing helper for |
13
|
|
|
|
|
|
|
#pod L<REST|http://en.wikipedia.org/wiki/Representational_state_transfer>ful |
14
|
|
|
|
|
|
|
#pod L<CRUD|http://en.wikipedia.org/wiki/Create,_read,_update_and_delete> |
15
|
|
|
|
|
|
|
#pod operations via HTTP to the app. |
16
|
|
|
|
|
|
|
#pod |
17
|
|
|
|
|
|
|
#pod The routes are intended, but not restricted to be used by AJAX applications. |
18
|
|
|
|
|
|
|
#pod |
19
|
|
|
|
|
|
|
#pod =cut |
20
|
|
|
|
|
|
|
|
21
|
1
|
|
|
1
|
|
1442
|
use Lingua::EN::Inflect qw/PL/; |
|
1
|
|
|
|
|
15202
|
|
|
1
|
|
|
|
|
603
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#pod =method register |
24
|
|
|
|
|
|
|
#pod |
25
|
|
|
|
|
|
|
#pod Adds the routing helper. Is called by Mojolicious. |
26
|
|
|
|
|
|
|
#pod |
27
|
|
|
|
|
|
|
#pod =cut |
28
|
|
|
|
|
|
|
sub register { |
29
|
1
|
|
|
1
|
1
|
14461
|
my ($self, $app) = @_; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
#pod =mojo_short rest_routes |
32
|
|
|
|
|
|
|
#pod |
33
|
|
|
|
|
|
|
#pod Can be used to easily generate the needed RESTful routes for a resource. |
34
|
|
|
|
|
|
|
#pod |
35
|
|
|
|
|
|
|
#pod my $userroute = $self->rest_routes(name => 'user'); |
36
|
|
|
|
|
|
|
#pod |
37
|
|
|
|
|
|
|
#pod # Installs the following routes (given that $r->namespaces == ['My::Mojo']): |
38
|
|
|
|
|
|
|
#pod # GET /api/users --> My::Mojo::User::rest_list() |
39
|
|
|
|
|
|
|
#pod # POST /api/users --> My::Mojo::User::rest_create() |
40
|
|
|
|
|
|
|
#pod # GET /api/users/:userid --> My::Mojo::User::rest_show() |
41
|
|
|
|
|
|
|
#pod # PUT /api/users/:userid --> My::Mojo::User::rest_update() |
42
|
|
|
|
|
|
|
#pod # DELETE /api/users/:userid --> My::Mojo::User::rest_remove() |
43
|
|
|
|
|
|
|
#pod |
44
|
|
|
|
|
|
|
#pod I<Please note>: plural forms will be used in the route, i.e. "users" instead of "user". |
45
|
|
|
|
|
|
|
#pod |
46
|
|
|
|
|
|
|
#pod You can also chain C<rest_routes>: |
47
|
|
|
|
|
|
|
#pod |
48
|
|
|
|
|
|
|
#pod $userroute->rest_routes(name => 'hat', readonly => 1); |
49
|
|
|
|
|
|
|
#pod |
50
|
|
|
|
|
|
|
#pod # Installs the following additional routes: |
51
|
|
|
|
|
|
|
#pod # GET /api/users/:userid/hats --> My::Mojo::Hat::rest_list() |
52
|
|
|
|
|
|
|
#pod # GET /api/users/:userid/hats/:hatid --> My::Mojo::Hat::rest_show() |
53
|
|
|
|
|
|
|
#pod |
54
|
|
|
|
|
|
|
#pod The target controller has to implement the following methods: |
55
|
|
|
|
|
|
|
#pod |
56
|
|
|
|
|
|
|
#pod =for :list |
57
|
|
|
|
|
|
|
#pod * C<rest_list> |
58
|
|
|
|
|
|
|
#pod * C<rest_create> |
59
|
|
|
|
|
|
|
#pod * C<rest_show> |
60
|
|
|
|
|
|
|
#pod * C<rest_update> |
61
|
|
|
|
|
|
|
#pod * C<rest_remove> |
62
|
|
|
|
|
|
|
#pod |
63
|
|
|
|
|
|
|
#pod B<Parameters to control the route creation> |
64
|
|
|
|
|
|
|
#pod |
65
|
|
|
|
|
|
|
#pod =over |
66
|
|
|
|
|
|
|
#pod |
67
|
|
|
|
|
|
|
#pod =item name |
68
|
|
|
|
|
|
|
#pod |
69
|
|
|
|
|
|
|
#pod The name of the resource, e.g. a "user", a "book" etc. This name will be used to |
70
|
|
|
|
|
|
|
#pod build the route URL as well as the controller name (see example above). |
71
|
|
|
|
|
|
|
#pod |
72
|
|
|
|
|
|
|
#pod =item readonly (optional) |
73
|
|
|
|
|
|
|
#pod |
74
|
|
|
|
|
|
|
#pod If set to 1, no create/update/delete routes will be created |
75
|
|
|
|
|
|
|
#pod |
76
|
|
|
|
|
|
|
#pod =item controller (optional) |
77
|
|
|
|
|
|
|
#pod |
78
|
|
|
|
|
|
|
#pod Default behaviour is to use the resource name to build the CamelCase controller |
79
|
|
|
|
|
|
|
#pod name (this is done by L<Mojolicious::Routes::Route>). You can change this by |
80
|
|
|
|
|
|
|
#pod directly specifying the controller's name via the I<controller> attribute. |
81
|
|
|
|
|
|
|
#pod |
82
|
|
|
|
|
|
|
#pod Note that you have to give the real controller class name (i.e. CamelCased or |
83
|
|
|
|
|
|
|
#pod whatever you class name looks like) including the full namespace. |
84
|
|
|
|
|
|
|
#pod |
85
|
|
|
|
|
|
|
#pod $self->rest_routes(name => 'user', controller => 'My::Mojo::Person'); |
86
|
|
|
|
|
|
|
#pod |
87
|
|
|
|
|
|
|
#pod # Installs the following routes: |
88
|
|
|
|
|
|
|
#pod # GET /api/users --> My::Mojo::Person::rest_list() |
89
|
|
|
|
|
|
|
#pod # ... |
90
|
|
|
|
|
|
|
#pod |
91
|
|
|
|
|
|
|
#pod =back |
92
|
|
|
|
|
|
|
#pod |
93
|
|
|
|
|
|
|
#pod B<How to retrieve the parameters / IDs> |
94
|
|
|
|
|
|
|
#pod |
95
|
|
|
|
|
|
|
#pod There are two ways to retrieve the IDs given by the client in your C<rest_show>, |
96
|
|
|
|
|
|
|
#pod C<rest_update> and C<rest_remove> methods. |
97
|
|
|
|
|
|
|
#pod |
98
|
|
|
|
|
|
|
#pod Example request: C<GET /api/users/5/hats/no9> |
99
|
|
|
|
|
|
|
#pod |
100
|
|
|
|
|
|
|
#pod 1. New way: the stash entry C<fm.ids> holds a hash with all ids: |
101
|
|
|
|
|
|
|
#pod |
102
|
|
|
|
|
|
|
#pod package My::Mojo::Hats; |
103
|
|
|
|
|
|
|
#pod use Mojo::Base 'Mojolicious::Controller'; |
104
|
|
|
|
|
|
|
#pod |
105
|
|
|
|
|
|
|
#pod sub rest_show { |
106
|
|
|
|
|
|
|
#pod use Data::Dump qw(dump); |
107
|
|
|
|
|
|
|
#pod print dump($self->stash('fm.ids')); |
108
|
|
|
|
|
|
|
#pod |
109
|
|
|
|
|
|
|
#pod # { user => 5, hat => 'no9' } |
110
|
|
|
|
|
|
|
#pod } |
111
|
|
|
|
|
|
|
#pod |
112
|
|
|
|
|
|
|
#pod 2. Old way: for each resource there will be a parameter C<***id>, e.g.: |
113
|
|
|
|
|
|
|
#pod |
114
|
|
|
|
|
|
|
#pod package My::Mojo::Hat; |
115
|
|
|
|
|
|
|
#pod use Mojo::Base 'Mojolicious::Controller'; |
116
|
|
|
|
|
|
|
#pod |
117
|
|
|
|
|
|
|
#pod sub rest_show { |
118
|
|
|
|
|
|
|
#pod my ($self) = @_; |
119
|
|
|
|
|
|
|
#pod my $user = $self->param('userid'); |
120
|
|
|
|
|
|
|
#pod my $hat = $self->param('hatid'); |
121
|
|
|
|
|
|
|
#pod return $self->render(text => "$userid, $hatid"); |
122
|
|
|
|
|
|
|
#pod |
123
|
|
|
|
|
|
|
#pod # text: "5, no9" |
124
|
|
|
|
|
|
|
#pod } |
125
|
|
|
|
|
|
|
#pod |
126
|
|
|
|
|
|
|
#pod Furthermore, the parameter C<idname> holds the name of the last ID in the route: |
127
|
|
|
|
|
|
|
#pod |
128
|
|
|
|
|
|
|
#pod package My::Mojo::Hat; |
129
|
|
|
|
|
|
|
#pod use Mojo::Base 'Mojolicious::Controller'; |
130
|
|
|
|
|
|
|
#pod |
131
|
|
|
|
|
|
|
#pod sub rest_show { |
132
|
|
|
|
|
|
|
#pod my $p_name = $self->param('idname'); |
133
|
|
|
|
|
|
|
#pod my $id = $self->param($p_name); |
134
|
|
|
|
|
|
|
#pod return $self->render(text => sprintf("%s = %s", $p_name, $id || '')); |
135
|
|
|
|
|
|
|
#pod |
136
|
|
|
|
|
|
|
#pod # text: "hatid = 5" |
137
|
|
|
|
|
|
|
#pod } |
138
|
|
|
|
|
|
|
#pod |
139
|
|
|
|
|
|
|
#pod =cut |
140
|
|
|
|
|
|
|
# For the following TODOs also see http://pastebin.com/R9zXrtCg |
141
|
|
|
|
|
|
|
# TODO Add GET /api/users/new --> rest_create_user_form |
142
|
|
|
|
|
|
|
# TODO Add GET /api/users/:userid/edit --> rest_edit_user_form |
143
|
|
|
|
|
|
|
# TODO Add GET /api/users/:userid/delete --> rest_delete_user_form |
144
|
|
|
|
|
|
|
# TODO Add GET /api/users/search --> rest_search_user_form |
145
|
|
|
|
|
|
|
# TODO Add PUT /api/users/search/:term --> rest_search_user_form (submit/execution) |
146
|
|
|
|
|
|
|
$app->routes->add_shortcut( |
147
|
|
|
|
|
|
|
rest_routes => sub { |
148
|
3
|
|
|
3
|
|
761
|
my $r = shift; |
149
|
3
|
50
|
|
|
|
18
|
my $params = { @_ ? (ref $_[0] ? %{ $_[0] } : @_) : () }; |
|
0
|
50
|
|
|
|
0
|
|
150
|
|
|
|
|
|
|
|
151
|
3
|
|
|
|
|
6
|
my $name = $params->{name}; |
152
|
3
|
|
100
|
|
|
12
|
my $readonly = $params->{readonly} || 0; |
153
|
3
|
|
66
|
|
|
10
|
my $controller = $params->{controller} || "$name#"; |
154
|
|
|
|
|
|
|
|
155
|
3
|
|
|
|
|
14
|
my $plural = PL($name, 10); |
156
|
|
|
|
|
|
|
|
157
|
3
|
|
|
|
|
4353
|
$app->log->info("Creating REST routes for resource '$name' (controller: $controller)"); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# |
160
|
|
|
|
|
|
|
# Generate "/$name" route, handled by controller $name |
161
|
|
|
|
|
|
|
# |
162
|
3
|
|
|
|
|
141
|
my $resource = $r->route("/$plural")->to($controller); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# GET requests - lists the collection of this resource |
165
|
3
|
|
|
|
|
1394
|
$resource->get->to('#rest_list')->name("list_$plural"); |
166
|
3
|
|
|
|
|
944
|
$app->log->debug("Created route GET ".$r->to_string."/$plural (rest_list)"); |
167
|
|
|
|
|
|
|
|
168
|
3
|
100
|
|
|
|
469
|
if (!$readonly) { |
169
|
|
|
|
|
|
|
# POST requests - creates a new resource |
170
|
1
|
|
|
|
|
5
|
$resource->post->to('#rest_create')->name("create_$name"); |
171
|
1
|
|
|
|
|
341
|
$app->log->debug("Created route POST ".$r->to_string."/$plural (rest_create)"); |
172
|
|
|
|
|
|
|
}; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# |
175
|
|
|
|
|
|
|
# Generate "/$name/:id" route, also handled by controller $name |
176
|
|
|
|
|
|
|
# |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# resource routes might be chained, so we need to define an |
179
|
|
|
|
|
|
|
# individual id and pass its name to the controller (idname) |
180
|
|
|
|
|
|
|
$resource = $r |
181
|
|
|
|
|
|
|
->bridge("/$plural/:${name}id") |
182
|
|
|
|
|
|
|
->to(cb => sub { |
183
|
10
|
|
|
|
|
458765
|
my ($c) = @_; |
184
|
10
|
|
|
|
|
170
|
$c->app->log->debug(sprintf("Feeding ID into stash: \$c->stash('fm.ids')->{'%s'} = %s", $name, $c->param("${name}id"))); |
185
|
10
|
100
|
|
|
|
1077
|
$c->stash('fm.ids' => {}) unless $c->stash('fm.ids'); |
186
|
10
|
|
|
|
|
230
|
$c->stash('fm.ids')->{$name} = $c->param("${name}id"); |
187
|
|
|
|
|
|
|
}) |
188
|
3
|
|
|
|
|
131
|
->route->to($controller, idname => "${name}id"); |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# GET requests - lists a single resource |
191
|
3
|
|
|
|
|
2028
|
$resource->get->to('#rest_show')->name("show_$name"); |
192
|
3
|
|
|
|
|
942
|
$app->log->debug("Created route GET ".$r->to_string."/$plural/:${name}id (rest_show)"); |
193
|
|
|
|
|
|
|
|
194
|
3
|
100
|
|
|
|
493
|
if (!$readonly) { |
195
|
|
|
|
|
|
|
# DELETE requests - deletes a resource |
196
|
1
|
|
|
|
|
5
|
$resource->delete->to('#rest_remove')->name("delete_$name"); |
197
|
1
|
|
|
|
|
308
|
$app->log->debug("Created route DELETE ".$r->to_string."/$plural/:${name}id (rest_delete)"); |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
# PUT requests - updates a resource |
200
|
1
|
|
|
|
|
124
|
$resource->put->to('#rest_update')->name("update_$name"); |
201
|
1
|
|
|
|
|
341
|
$app->log->debug("Created route PUT ".$r->to_string."/$plural/:${name}id (rest_update)"); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
# return "/$name/:id" route so that potential child routes make sense |
205
|
3
|
|
|
|
|
135
|
return $resource; |
206
|
|
|
|
|
|
|
} |
207
|
1
|
|
|
|
|
18
|
); |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
1; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
__END__ |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=pod |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head1 NAME |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Mojolicious::Plugin::RESTRoutes - routing helper for RESTful operations |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=head1 VERSION |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
version 0.010011 |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=head1 DESCRIPTION |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
This Mojolicious plugin adds a routing helper for |
227
|
|
|
|
|
|
|
L<REST|http://en.wikipedia.org/wiki/Representational_state_transfer>ful |
228
|
|
|
|
|
|
|
L<CRUD|http://en.wikipedia.org/wiki/Create,_read,_update_and_delete> |
229
|
|
|
|
|
|
|
operations via HTTP to the app. |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
The routes are intended, but not restricted to be used by AJAX applications. |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=head1 MOJOLICIOUS SHORTCUTS |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=head2 rest_routes |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
Can be used to easily generate the needed RESTful routes for a resource. |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
my $userroute = $self->rest_routes(name => 'user'); |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Installs the following routes (given that $r->namespaces == ['My::Mojo']): |
242
|
|
|
|
|
|
|
# GET /api/users --> My::Mojo::User::rest_list() |
243
|
|
|
|
|
|
|
# POST /api/users --> My::Mojo::User::rest_create() |
244
|
|
|
|
|
|
|
# GET /api/users/:userid --> My::Mojo::User::rest_show() |
245
|
|
|
|
|
|
|
# PUT /api/users/:userid --> My::Mojo::User::rest_update() |
246
|
|
|
|
|
|
|
# DELETE /api/users/:userid --> My::Mojo::User::rest_remove() |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
I<Please note>: plural forms will be used in the route, i.e. "users" instead of "user". |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
You can also chain C<rest_routes>: |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
$userroute->rest_routes(name => 'hat', readonly => 1); |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# Installs the following additional routes: |
255
|
|
|
|
|
|
|
# GET /api/users/:userid/hats --> My::Mojo::Hat::rest_list() |
256
|
|
|
|
|
|
|
# GET /api/users/:userid/hats/:hatid --> My::Mojo::Hat::rest_show() |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
The target controller has to implement the following methods: |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=over 4 |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=item * |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
C<rest_list> |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=item * |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
C<rest_create> |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item * |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
C<rest_show> |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item * |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
C<rest_update> |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=item * |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
C<rest_remove> |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=back |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
B<Parameters to control the route creation> |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=over |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=item name |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
The name of the resource, e.g. a "user", a "book" etc. This name will be used to |
291
|
|
|
|
|
|
|
build the route URL as well as the controller name (see example above). |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=item readonly (optional) |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
If set to 1, no create/update/delete routes will be created |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=item controller (optional) |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Default behaviour is to use the resource name to build the CamelCase controller |
300
|
|
|
|
|
|
|
name (this is done by L<Mojolicious::Routes::Route>). You can change this by |
301
|
|
|
|
|
|
|
directly specifying the controller's name via the I<controller> attribute. |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
Note that you have to give the real controller class name (i.e. CamelCased or |
304
|
|
|
|
|
|
|
whatever you class name looks like) including the full namespace. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
$self->rest_routes(name => 'user', controller => 'My::Mojo::Person'); |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# Installs the following routes: |
309
|
|
|
|
|
|
|
# GET /api/users --> My::Mojo::Person::rest_list() |
310
|
|
|
|
|
|
|
# ... |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=back |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
B<How to retrieve the parameters / IDs> |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
There are two ways to retrieve the IDs given by the client in your C<rest_show>, |
317
|
|
|
|
|
|
|
C<rest_update> and C<rest_remove> methods. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Example request: C<GET /api/users/5/hats/no9> |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
1. New way: the stash entry C<fm.ids> holds a hash with all ids: |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
package My::Mojo::Hats; |
324
|
|
|
|
|
|
|
use Mojo::Base 'Mojolicious::Controller'; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub rest_show { |
327
|
|
|
|
|
|
|
use Data::Dump qw(dump); |
328
|
|
|
|
|
|
|
print dump($self->stash('fm.ids')); |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# { user => 5, hat => 'no9' } |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
2. Old way: for each resource there will be a parameter C<***id>, e.g.: |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
package My::Mojo::Hat; |
336
|
|
|
|
|
|
|
use Mojo::Base 'Mojolicious::Controller'; |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub rest_show { |
339
|
|
|
|
|
|
|
my ($self) = @_; |
340
|
|
|
|
|
|
|
my $user = $self->param('userid'); |
341
|
|
|
|
|
|
|
my $hat = $self->param('hatid'); |
342
|
|
|
|
|
|
|
return $self->render(text => "$userid, $hatid"); |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
# text: "5, no9" |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Furthermore, the parameter C<idname> holds the name of the last ID in the route: |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
package My::Mojo::Hat; |
350
|
|
|
|
|
|
|
use Mojo::Base 'Mojolicious::Controller'; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
sub rest_show { |
353
|
|
|
|
|
|
|
my $p_name = $self->param('idname'); |
354
|
|
|
|
|
|
|
my $id = $self->param($p_name); |
355
|
|
|
|
|
|
|
return $self->render(text => sprintf("%s = %s", $p_name, $id || '')); |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
# text: "hatid = 5" |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head1 METHODS |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
=head2 register |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
Adds the routing helper. Is called by Mojolicious. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=encoding utf8 |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=head1 AUTHOR |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Jens Berthold <cpan-mp-restroutes@jebecs.de> |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
This software is Copyright (c) 2015 by Jens Berthold. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
This is free software, licensed under: |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
The MIT (X11) License |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=cut |