diff options
Diffstat (limited to '')
| -rw-r--r-- | posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org b/posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org new file mode 100644 index 0000000..a1e56a5 --- /dev/null +++ b/posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org @@ -0,0 +1,169 @@ +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]]. |
