[Dancer-users] Dancer::Plugin::REST proposal

Naveed Massjouni naveedm9 at gmail.com
Sun Dec 26 06:50:55 CET 2010


DISCLAIMER:
I know this is the mailing list for Dancer, but I am writing about a
particular plugin.  I think it is relevant because it is a pretty
important plugin and also because I would like to hear everyone's
opinion.  Especially Sukria, since it's his plugin.

There has been several REST related posts recently and it has reminded
me of something that has been bugging me about the
Dancer::Plugin::REST module.  It provides the keyword resource which
works as follows:

    resource user =>
        get    => sub { # return user where id = params->{id}   },
        create => sub { # create a new user with params->{user} },
        delete => sub { # delete user where id = params->{id}   },
        update => sub { # update user with params->{user}       };

But a PUT/POST in REST does not always correspond to UPDATE/CREATE.
One of my favorite articles on this topic is:

http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/

It's worth reading even if you don't agree with it in the end.  It
will at least show you a different perspective.  Also, his argument is
backed up by the HTTP spec.  He argues that a PUT can be used to
update or create a resource, and the same for a POST.

So I have some proposals that could make everyone happy, hopefully.
Even if you are happy with the existing CRUD mapping.  I think the
REST plugin should also support mappings from a resource to http
verbs, in addition to the way it works now.  For example:

    resource user =>
        get    => sub { # return user where id = params->{id}   },
        create => sub { # create a new user with params->{user} },
        delete => sub { # delete user where id = params->{id}   },
        update => sub { # update user with params->{user}       },
        # and also
        post   => sub { },
        put    => sub { };

Even better is if it supported a dispatch table style:

    resource user => {
        get    => sub { },
        delete => sub { },
        post   => sub { },
        put    => sub { },
    };

Notice that the second argument to 'resource' is a hashref in the
above example.  Another cool thing it could support is:

    resource user => 'User';

Where 'User' is a package/class that could be defined in User.pm:

    package User;
    sub get { ... }
    sub delete { ... }
    sub post { ... }
    sub put { ... }
    1;

Another thing that could be improved is that the 'resource' function
throws an exception if the user did not provide mappings for all 4
operations/verbs.  But there is no requirement that a resource should
support all http verbs.  The 'resource' function could provide routes
which return a status of 405 Method Not Allowed, for the missing
verbs.

Do you guys like any of these ideas?  Should these ideas be
incorporated into the existing REST plugin or a new plugin?  I would
be glad to implement them, but I wanted to make sure my changes would
be accepted before doing the work.

Regards,
Naveed


More information about the Dancer-users mailing list