blob: a1e56a56a94bf2869b25b2a16deda0ac3b71f678 (
plain) (
tree)
|
|
This week, with [[http://www.sukria.net/fr/][Alexi]]'s help,
[[http://github.com/perldancer/Dancer][I've been working on]] to add
auto-(de)serialization to Dancer's request. This features will be
available in the next [[http://perldancer.org/][Dancer]] version, the
1.170 (which will be out before April).
The basic idea was to provides to developer a simple way to access data
that have been send in a serialized format, and to properly serialize
the response.
At the moment, the supported serializers are :
- Dancer::Serialize::JSON
- Dancer::Serialize::YAML
- Dancer::Serialize::XML
- Dancer::Serialize::Mutable
** Configuring an application to use the serializer
To activate serialization in your application:
#+BEGIN_SRC perl
set serializer => 'JSON';
#+END_SRC
or in your configuration file:
#+BEGIN_EXAMPLE
serializer: "JSON"
#+END_EXAMPLE
** A simple handler
Let's create a new dancer application (you can fetch the source on
[[http://git.lumberjaph.net/p5-dancer-rest.git/][my git server]] :
#+BEGIN_EXAMPLE
% dancer -a dancerREST
% cd dancerREST
% vim dancerREST.pm
#+END_EXAMPLE
then
#+BEGIN_SRC perl
package dancerREST;
use Dancer ':syntax';
my %users = ();
post '/api/user/' => sub {
my $params = request->params;
if ($params->{name} && $params->{id}) {
if (exists $users{$params->{id}}) {
return {error => "user already exists"};
}
$users{$params->{id}} = {name => $params->{name}};
return {id => $params->{id}, name => $params->{name}};
}
else {
return {error => "name is missing"};
}
};
true;
#+END_SRC
We can test if everything works as expected:
#+BEGIN_EXAMPLE
% plackup app.psgi &
% curl -H "Content-Type: application/json" -X POST http://localhost:5000/api/user/ -d '{"name":"foo","id":1}'
# => {"name":"foo","id":"1"}
#+END_EXAMPLE
Now we add a method to fetch a list of users, and a method to get a
specific user:
#+BEGIN_SRC perl
# return a specific user
get '/api/user/:id' => sub {
my $params = request->params;
if (exists $users{$params->{id}}) {
return $users{$params->{id}};
}
else {
return {error => "unknown user"};
}
};
# return a list of users
get '/api/user/' => sub {
my @users;
push @users, {name => $users{$_}->{name}, id => $_}
foreach keys %users;
return \@users;
};
#+END_SRC
If we want to fetch the full list:
#+BEGIN_SRC sh
curl -H "Content-Type: application/json" http://localhost:5000/api/user/
# => [{"name":"foo","id":"1"}]
#+END_SRC
and a specific user:
#+BEGIN_SRC sh
curl -H "Content-Type: application/json" http://localhost:5000/api/user/1
# => {"name":"foo"}
#+END_SRC
** The mutable serializer
The mutable serializer will try to load an appropriate serializer
guessing from the *Content-Type* and *Accept-Type* header. You can also
overload this by adding a *content\_type=application/json* parameter to
your request.
While setting your serializer to mutable, your let your user decide
which format they prefer between YAML, JSON and XML.
** And the bonus
Dancer provides now a new method to the request object : =is_ajax=. Now
you can write something like
#+BEGIN_SRC perl
get '/user/:id' => sub {
my $params = request->params;
my $user = $users{$params->{id}};
my $result;
if (!$user) {
_render_user({error => "unknown user"});
}
else {
_render_user($user);
}
};
sub _render_user {
my $result = shift;
if (request->is_ajax) {
return $result;
}
else {
template 'user.tt', $result;
}
}
#+END_SRC
If we want to simulate an AJAX query:
#+BEGIN_EXAMPLE
% curl -H "X-Requested-With: XMLHttpRequest" http://localhost:5000/user/1
#+END_EXAMPLE
and we will obtain our result in JSON. But we can also test without the
X-Requested-With:
#+BEGIN_EXAMPLE
% curl http://localhost:5000/user/1
#+END_EXAMPLE
and the template will be rendered.
Hope you like this new features. I've also been working on something
similar for [[http://github.com/miyagawa/tatsumaki][Tatsumaki]].
|