summaryrefslogblamecommitdiff
path: root/_posts/2010-03-19-easily-create-rest-interface-with-the-dancer-1.170.md
blob: 3ddf3a46d0b19c07884f818d2ddf33f8701f16fa (plain) (tree)
1
2
3
4
5
6
7
8
9

            
                                                                             


                                                         
                                                                                                                                                                                                                                                                                                           
 
                                                                                                                                                           


                                              



                            
 
                                                   


                                              


                         


                              


                    
 
                   
 
                                                                                                                                   
 
                    


                      
                  



























                                                              
                    

                                                                                                             
                            
                  


























                                                                   

                                                                        
                              
                  


                    

                                                                         
                   
                  
 
                         
 
                                                                                                                                                                                                                                    


                                                                                                                        
                
 
                                                                                                    


























                                                
                    
                                                                         
                  


                                                                                         
                    
                                   
                  


                                  
                                                                                                                                   
---
layout: post
summary: In which we see that it's easy to create REST interface with Dancer.
title: Easily create REST interface with the Dancer 1.170
---

This week, with [Alexi](http://www.sukria.net/fr/)'s help, [I've been working on](http://github.com/perldancer/Dancer) to add auto-(de)serialization to Dancer's request. This features will be available in the next [Dancer](http://perldancer.org/) 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:

{% highlight perl %}
set serializer => 'JSON';
{% endhighlight %}

or in your configuration file:

{% highlight yaml %}
serializer: "JSON"
{% endhighlight %}

## A simple handler

Let's create a new dancer application (you can fetch the source on [my git server](http://git.lumberjaph.net/p5-dancer-rest.git/) :

{% highlight bash %}
% dancer -a dancerREST
% cd dancerREST
% vim dancerREST.pm
{% endhighlight %}

then

{% highlight 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;
{% endhighlight %}

We can test if everything works as expected:

{% highlight bash %}
% 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"}
{% endhighlight %}

Now we add a method to fetch a list of users, and a method to get a
specific user:

{% highlight 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;
};
{% endhighlight %}

If we want to fetch the full list:

{% highlight sh %}
curl -H "Content-Type: application/json" http://localhost:5000/api/user/
# => [{"name":"foo","id":"1"}]
{% endhighlight %}

and a specific user:

{% highlight sh %}
curl -H "Content-Type: application/json" http://localhost:5000/api/user/1
# => {"name":"foo"}
{% endhighlight %}

## 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

{% highlight 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;
    }
}
{% endhighlight %}

If we want to simulate an AJAX query:

{% highlight bash %}
% curl -H "X-Requested-With: XMLHttpRequest" http://localhost:5000/user/1
{% endhighlight %}

and we will obtain our result in JSON. But we can also test without the X-Requested-With:

{% highlight bash %}
% curl http://localhost:5000/user/1
{% endhighlight %}

and the template will be rendered.

Hope you like this new features. I've also been working on something similar for [Tatsumaki](http://github.com/miyagawa/tatsumaki).