summaryrefslogtreecommitdiff
path: root/posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org
diff options
context:
space:
mode:
Diffstat (limited to 'posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org')
-rw-r--r--posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.org169
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]].