[Dancer-users] a Dance for the REST of us

Puneet Kishor punk.kish at gmail.com
Fri Dec 24 04:40:17 CET 2010


Very clear explanation, thanks. A couple of questions follow (see below)...

Flavio Poletti wrote:
> I don't know much about REST, but the base should be that you have to
> map the thing you want to do upon HTTP methods, which have a
> well-defined semantics. In particular, if you want to...
>
> ... get some data, without having collateral effects on the data => use
> HTTP GET
> ... modify some existing data => use HTTP POST
> ... add some data => use HTTP PUT
> ... delete some data => use HTTP DELETE
>
> Dancer happens to support the four methods via the usual route
> definition approach, with lowercase functions for each HTTP METHOD,
> except that (HTTP) DELETE is called "del" (this is due to the fact that
> "delete" is a built-in keyword in Perl and it's better to leave it alone).
>
> So, if you want to delete something under the REST umbrella, you're
> supposed to use Dancer's "del" instead of "get":
>
> del '/:foo_id' => sub { ... }

Right, that is on the dancer side. What is it going to be on the browser 
side? In my Javascript, I have

     $.ajax({
         url     : "http://server/foo/" + foo_id,
         type    : "GET",
         data    : "",
         dataType: "json",
         error   : function() { alert("Error loading html document"); },
         success : function(data) {
              alert("Foo " + foo_id + " was successfully deleted");
         }
     });

So, from the browser's perspective, I am still sending an http get 
request, correct? Or, should that "type:" above really be a "DELETE" 
instead of a "GET"?

Of course, if that is the case, then, from the browser's perspective, 
there is no difference between a get request that deletes and a get 
request that really gets.


>
> Regarding the ordering, there is an example in the "ACTION SKIPPING"
> section of Dancer::Introduction, even though the example is a bit wrong
> because it does not include the due "return" before pass (see
> documentation about "pass" for this). This is how it should be:
>
>
>      get'/say/:word'  =>  sub {
>          return pass if (params->{word} =~ /^\d+$/);
>          "I say a word:".params->{word};
>      };
>
>      get'/say/:number'  =>  sub {
>          "I say a number:".params->{number};
>      };
>

This is a bit worrisome as I have to get my ordering really correct. I 
guess I could first have all the routes that are identified by specific 
keywords ("all", "new", "save", etc.), and then end with the route that 
is just an id.

If I get the ordering wrong, I can end up with unexpected results.

I have another question regarding putting only similar routes in a 
single package, but I will save that for another email.


>
> Cheers,
>
>     Flavio.
>
>
>
>
> On Fri, Dec 24, 2010 at 12:42 AM, Puneet Kishor <punk.kish at gmail.com
> <mailto:punk.kish at gmail.com>> wrote:
>
>     I have widgets called "foo," and I am building web app that will
>     also serve as a RESTful app for data access via the command line.
>     All "foo" related routes are packaged together, and are loaded via
>         `load_app "app::foo", prefix => "/foo"`
>
>     so that `get '/:foo_id'` really become `http://server/foo/:foo_id`
>     <http://server/foo/:foo_id>.
>
>     My routes are
>
>     1. get '/'
>     ===========
>     Returns a welcome page via a full html request. A full html request
>     is where a full web page is loaded, as opposed to an ajax request
>     where only a part of the web page is refreshed.
>
>     2. get '/all'
>     ==============
>     Returns minimal info for all valid "foo" from the data store via a
>     full html request. However, I would also like to return them as a
>     json string via the command line. Now, when requested via the web
>     browser, this method should really return only some minimal info for
>     each "foo." Clicking on any specific "foo" should fire #3 below to
>     get its details -- a typical drill-down application. However, when
>     requested via the commandline, there should be an option to return
>     *all* the details, with some checks, so that gigabytes of data are
>     not returned.
>
>     3. get '/:foo_id'
>     ==================
>     Returns all the details for a specific "foo" as a json string via an
>     ajax request.
>
>     4. get '/new'
>     ==============
>     Returns a page to begin constructing a new "foo" in the browser via
>     a full html request. There is no equivalent command line method for
>     this.
>
>     5. post '/save'
>     =======================
>     Saves a new "foo" created in #4 or above, or via a command line
>     method. In other words, a user should be able to supply in a json
>     string via the command line everything that a user would create
>     interactively in #4 above.
>
>     6. get '/delete/:foo_id'
>     =========================
>     This method removed a specific foo. Now, two things I don't
>     understand about this -- one, of course, in a RESTful app, this
>     would be a DELETE method. This is a bit confusing to me -- is the
>     HTTP get (I am using a lowercase 'get') not the same as a REST GET
>     (using an uppercase get)? In other words, can I use a `get` to
>     perform a `DELETE`? Two, how do I send authentication? I don't want
>     Sukrieh deleting Sawyer's widget.
>
>     In fact, this authentication theme runs through all the routes -- do
>     I just pass a session token for authentication with every route?
>
>     Finally, should #3 be the last route? Else, how do I differentiate
>     between `get '/delete/5'` and `get '/5'` and `get '/all'`?
>
>     Thanks in advance for a quick lesson, whosoever cares to give one.
>
>
>
>     --
>     Puneet Kishor
>     _______________________________________________
>     Dancer-users mailing list
>     Dancer-users at perldancer.org <mailto:Dancer-users at perldancer.org>
>     http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>
>



-- 
Puneet Kishor http://punkish.org
Carbon Model http://carbonmodel.org
Charter Member, Open Source Geospatial Foundation http://www.osgeo.org
Science Fellow http://creativecommons.org/about/people/fellows#puneetkishor
Nelson Institute, UW-Madison http://www.nelson.wisc.edu
---------------------------------------------------------------------------
Assertions are politics; backing up assertions with evidence is science
===========================================================================


More information about the Dancer-users mailing list