Dispatching based on HTTP method

1 view
Skip to first unread message

Hannes Wallnoefer

unread,
Jun 6, 2010, 4:23:52 AM6/6/10
to RingoJS
When I wrote the ringo webapp request dispatching code, one idea was
to allow both very generic and very specific URL mappings. For
example, on the generic side, you can simply forward all requests to a
single actions module:

exports.urls = ["", "myActions"];

or to some other request dispatching function implementing its own
dispatching logic:

exports.urls = ["", "myWebappFramwork", "dispatch"];

From its Helma legacy, Ringo has leaned to this generic, high level
style of mapping (auto-mapping to the exported functions of a module
is similar to Helma's mapping to actions of a HopObject). Because of
this, the means Ringo provides for specific url mappings may be a
little bit underdeveloped.

One thing people may be missing is dispatching based on HTTP method.
The last few days I've been thinking about how we could integrate this
into our current webapp dispatch syntax (or change the whole mechanism
to make it fit in). One idea I'm playing with is to allow including
the HTTP method in the pattern string, separated from the path pattern
with a space character:

exports.urls = [
["GET ^/document", "actions", "getDocument"],
["POST ^/document", "actions", "postDocument"],
["PUT ^/document", "actions", "putDocument"],
["DELETE ^/document", "actions", "deleteDocument"]
];

What I like about this is that it kind of reflects part of the first
line of a HTTP request:

GET /document/234987234 HTTP/1.1

What do you think?

Hannes

Hannes Wallnoefer

unread,
Jun 6, 2010, 5:01:15 AM6/6/10
to RingoJS
On Jun 6, 10:23 am, Hannes Wallnoefer <han...@helma.at> wrote:
>
> One thing people may be missing is dispatching based on HTTP method.
> The last few days I've been thinking about how we could integrate this
> into our current webapp dispatch syntax (or change the whole mechanism
> to make it fit in). One idea I'm playing with is to allow including
> the HTTP method in the pattern string, separated from the path pattern
> with a space character:
>
> exports.urls = [
>    ["GET ^/document", "actions", "getDocument"],
>    ["POST ^/document", "actions", "postDocument"],
>    ["PUT ^/document", "actions", "putDocument"],
>    ["DELETE ^/document", "actions", "deleteDocument"]
> ];

Oh wow, one thing that catches my eye is a way to extend our map-to-
module logic to cover this case:

exports.urls = ["", "actions"];

with actions exporting functions getDocument(req, id),
postDocument(req), incoming requests would be mapped as follows:

GET /document/123 -> getDocument(req, "123")
POST /document -> postDocument(req)
PUT /document -> NOT FOUND
DELETE /document/123 -> NOT FOUND

while with actions exporting a function called document(req), any
requests to /document not that don't have a method-specific action
would be mapped to that (provided that additional path elements can be
mapped to parameters).

That's not a substitute to my original proposal however, that one
still stands.

Hannes

Simon Oberhammer

unread,
Jun 6, 2010, 5:41:09 AM6/6/10
to RingoJS
["GET ^/document", "actions", "getDocument"],
["POST ^/document", "actions", "postDocument"],

i find that too far away from the actions that would implement the
matching behavior, e.g. deal with post data.

and the prefixes seem generic and not very transparent. such a
prefixes-dispatch would be something we'd have to immediately tell
every newcomer, even if they don't yet care about method dispatch.

disclaimer: i don't miss method dispatch, yet.
simon

Robert Thurnher

unread,
Jun 6, 2010, 6:18:46 AM6/6/10
to rin...@googlegroups.com
On 6 June 2010 11:01, Hannes Wallnoefer <han...@gmail.com> wrote:
> On Jun 6, 10:23 am, Hannes Wallnoefer <han...@helma.at> wrote:
>>
>> [...]

>>
>> exports.urls = [
>>    ["GET ^/document", "actions", "getDocument"],
>>    ["POST ^/document", "actions", "postDocument"],
>>    ["PUT ^/document", "actions", "putDocument"],
>>    ["DELETE ^/document", "actions", "deleteDocument"]
>> ];

First of all, really great to see some further thoughts and discussion on this.

Well, here's another (still pretty rough) idea thrown in:

// an-app/config.js

// [...]

exports.urls = [
["^/", "./actions"]
];


// an-app/actions.js

// [...]

// GET /documents
exports.GET.documents = function (req) {
// Do something.
};

// GET /documents/{id}
exports.GET.documents = function (req, id) {
// Do something.
};

// POST /documents/{id}
exports.POST.documents = function (req, id) {
// Do something.
};

// PUT /documents/{id}
exports.PUT.documents = function (req, id) {
// Do something.
};

// DELETE /documents/{id}
exports.DEL.documents = function (req, id) {
// Do something.
};


-- Robi

Robert Thurnher

unread,
Jun 6, 2010, 6:30:26 AM6/6/10
to rin...@googlegroups.com
On 6 June 2010 12:18, Robert Thurnher <r.thu...@gmail.com> wrote:
>
> // GET /documents
> exports.GET.documents = function (req) {
>    // Do something.
> };
>
> // GET /documents/{id}
> exports.GET.documents = function (req, id) {
>    // Do something.
> };

Well, the roughness shows, e.g., in that the above won't work this
way, of course (as in no method overloading in JS). :)

-- Robi

Robert Thurnher

unread,
Jun 6, 2010, 8:01:51 AM6/6/10
to rin...@googlegroups.com

Another iteration of the idea which could possibly actually work (somehow):
http://gist.github.com/427546

-- Robi

Hannes Wallnoefer

unread,
Jun 6, 2010, 8:17:42 AM6/6/10
to rin...@googlegroups.com
2010/6/6 Robert Thurnher <r.thu...@gmail.com>:


These are interesting ideas! However i think I would put it the other way round:

exports.documents = {
GET: function(req) {...},
POST: function(req) {...},
DELETE: function(req) {...}
};

To me it feels more natural this way around.

hannes

> -- Robi
>
> --
> You received this message because you are subscribed to the Google Groups "RingoJS" group.
> To post to this group, send email to rin...@googlegroups.com.
> To unsubscribe from this group, send email to ringojs+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/ringojs?hl=en.
>
>

Hannes Wallnoefer

unread,
Jun 7, 2010, 4:36:00 AM6/7/10
to RingoJS
On Jun 6, 11:01 am, Hannes Wallnoefer <hann...@gmail.com> wrote:
> On Jun 6, 10:23 am, Hannes Wallnoefer <han...@helma.at> wrote:
>
>
>
> > One thing people may be missing is dispatching based on HTTP method.
> > The last few days I've been thinking about how we could integrate this
> > into our current webapp dispatch syntax (or change the whole mechanism
> > to make it fit in). One idea I'm playing with is to allow including
> > the HTTP method in the pattern string, separated from the path pattern
> > with a space character:
>
> > exports.urls = [
> >    ["GET ^/document", "actions", "getDocument"],
> >    ["POST ^/document", "actions", "postDocument"],
> >    ["PUT ^/document", "actions", "putDocument"],
> >    ["DELETE ^/document", "actions", "deleteDocument"]
> > ];
>
> Oh wow, one thing that catches my eye is a way to extend our map-to-
> module logic to cover this case:
>
> exports.urls = ["", "actions"];
>
> with actions exporting functions getDocument(req, id),
> postDocument(req), incoming requests would be mapped as follows:
>
> GET /document/123  ->  getDocument(req, "123")
> POST /document  ->  postDocument(req)
> PUT /document  -> NOT FOUND
> DELETE /document/123  -> NOT FOUND

The problem with this is that it would expose get|pst|put|
deleteDocument actions for all methods, unless we put more code magic
in it, which I don't want to do. So let's forget this.

Hannes

Hannes Wallnoefer

unread,
Jun 7, 2010, 11:12:08 AM6/7/10
to RingoJS
On Jun 6, 2:17 pm, Hannes Wallnoefer <han...@helma.at> wrote:
> 2010/6/6 Robert Thurnher <r.thurn...@gmail.com>:
>
>
>
> > On 6 June 2010 12:30, Robert Thurnher <r.thurn...@gmail.com> wrote:
> >> On 6 June 2010 12:18, Robert Thurnher <r.thurn...@gmail.com> wrote:
>
> >>> // GET /documents
> >>> exports.GET.documents = function (req) {
> >>>    // Do something.
> >>> };
>
> >>> // GET /documents/{id}
> >>> exports.GET.documents = function (req, id) {
> >>>    // Do something.
> >>> };
>
> >> Well, the roughness shows, e.g., in that the above won't work this
> >> way, of course (as in no method overloading in JS). :)
>
> > Another iteration of the idea which could possibly actually work (somehow):
> >http://gist.github.com/427546
>
> These are interesting ideas! However i think I would put it the other way round:
>
> exports.documents = {
>     GET: function(req) {...},
>     POST: function(req) {...},
>     DELETE: function(req) {...}
>
> };
>
> To me it feels more natural this way around.

After some discussion on IRC with robi42 and oberhamsi, I implemented
and pushed the scheme above. It fits into the existing request
dispatching code quite easily - all it took were 4 lines of code.

For an example of how action code looks with this I posted a gist with
the converted demo app actions.js:

http://gist.github.com/428748

Now the two questions are:
1. Should we stick with this?
2. Should we convert all our actions it? (Responding irrespective of
HTTP method is not really something you normally want to do.)

Hannes

Emilis Dambauskas

unread,
Jun 8, 2010, 4:40:48 AM6/8/10
to rin...@googlegroups.com, Hannes Wallnoefer
On 06/07/2010 06:12 PM, Hannes Wallnoefer wrote:
> On Jun 6, 2:17 pm, Hannes Wallnoefer<han...@helma.at> wrote:
>
>> 2010/6/6 Robert Thurnher<r.thurn...@gmail.com>
>> These are interesting ideas! However i think I would put it the other way round:
>>
>> exports.documents = {
>> GET: function(req) {...},
>> POST: function(req) {...},
>> DELETE: function(req) {...}
>>
>> };
>>
>> To me it feels more natural this way around.
>>
> After some discussion on IRC with robi42 and oberhamsi, I implemented
> and pushed the scheme above. It fits into the existing request
> dispatching code quite easily - all it took were 4 lines of code.
>
> For an example of how action code looks with this I posted a gist with
> the converted demo app actions.js:
>
> http://gist.github.com/428748
>
> Now the two questions are:
> 1. Should we stick with this?
>
Yes it seems reasonable and convenient.

> 2. Should we convert all our actions it? (Responding irrespective of
> HTTP method is not really something you normally want to do.)
>
Please no.

It would add additional unnecessary code. And sometimes you have those
cases when you want to respond with the same result irrespective of HTTP
method.


--
Emilis Dambauskas

emil...@gmail.com
gsm: +370-686-07732
irc: emili...@irc.freenode.net
http://emilis.info

-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GAT/CC/MC/O dpu(-) s:- a- C++ UBLHS++ P(+) L+++ E--- W+++$ N+ o-- K? !w O? M-@ V? PS+(--) PE Y+>++ PGP t- 5? X+@ R- !tv b+ DI++++ D G e++ h---- r+++ y++++
------END GEEK CODE BLOCK------

Hannes Wallnoefer

unread,
Jun 8, 2010, 11:12:49 AM6/8/10
to RingoJS

On Jun 7, 5:12 pm, Hannes Wallnoefer <hann...@gmail.com> wrote:

> For an example of how action code looks with this I posted a gist with
> the converted demo app actions.js:
>
> http://gist.github.com/428748

After some heated discussion on IRC, we agreed to:

> Now the two questions are:
> 1. Should we stick with this?

yes

> 2. Should we convert all our actions it? (Responding irrespective of
> HTTP method is not really something you normally want to do.)

no

> Hannes
>
Reply all
Reply to author
Forward
0 new messages