On Nov 20, 2006, at 9:02 AM, A. Pagaltzis wrote:* Matt S Trout [2006-11-20 15:25]:
Feel free to propose a variant on the syntax marcus proposed
that will allow the implementation of equivalent functionality
without the addition of multimethods to the perl core.
Oh! Now I feel silly.
Eh.
OK, to lay out my own thinking a little, when I was doing my
silly PATHINFO-based hack-up of CGI::Prototype::Hidden, the plan
eventually became to have one class per handler, with methods
named after, err, methods, eg.:
sub GET { ... }
sub POST { ... }
sub HEAD { ... }
I still think that?s cleanest approach.
That's pretty much what I wound up doing. Except I was more focused
on a RESTful rewrite of InstantCRUD to generate one controller class
per table. It is very clean and simple. All my per-table controllers
inherited from a single base controller which implemented actions for
create, read, update, delete, edit, show, index.
Catalyst as it stands somewhat encourages a confusion between
nouns (URIs) and verbs (methods), with URIs like
`/entry/1234/comments/add`, where the `/entry/1234/comments` part
identifies a resource, but the `/add` bit at the end is really an
verb. That should simply be a POST to `/entry/1234/comments`.
I ended up disagreeing with the RoR folks and Audrey's REST work in
Jifty. I think leaving the key unspecified is a bad idea. Sometimes a
table has more than one primary key candidate. Or you may want to
limit the result set based on field that isn't a primary key. What I
implemented back around the same time as John Napiorkowski was
working on the same thing was:
/entry/id/1234/comments
vs.
/entry/surname,given_name/Pagaltzis,Aristotle/comments
vs.
/entry/status/open
And
most of the time, if the design is RESTful from the start, you
can implement a web app as pure CRUD using the HTTP methods; eg.
the methods in a controller should simply correspond 1:1 to HTTP
verbs. That was as far as I had gotten my own thoughts.
Of course, there are going to be some cases where that isn?t
quite enough; for these, you could have the option of adding
methods that work as if they were custom invented HTTP methods.
The framework could permit tunneling unsupported methods inside
POST requests, which it would automatically unravel before
dispatching. The Rails guys were doing something along these
lines; I have to take another look sometime.
I tunneled PUT and DELETE inside a POST via a "_method" body
parameter, which was automatically unravelled before dispatch within
an overridden Catalyst::prepare_body_parameters method.
I never did get around to supporting all the HTTP methods plus custom
extensions. I do agree that the :Method(...) style syntax is the way
to go.
What I don?t like about the current proposals in Catalyst-land
is that they make the RESTful approach a wordy non-default
option. It takes quite a bit of extra annotation with any of
them, even if each annotation is concise. It ends easier to just
put verbs in your URIs, where it should be just as easy to do it
properly.
I'm not sure I follow you. RESTful uri's end up being shorter. I
suppose you're talking about the pain associated with implementing a
RESTful interface within a catalyst app.
The annoying problem that I ran up against was:
1) Catalyst is designed with the assumption of dispatch based on
first match instead of best match. I.e. Catalyst::Dispatcher short
circuits on the first dispatch type attribute which matches. So side
effects in the dispatch type's ->match method aren't guaranteed if
multiple dispatch type parameters were specified.
2) All dispatch types are based on the request's path. If you want to
dispatch based on additional criterion, you're supposed to bury the
dispatch match logic in action classes.
Fast is good and well, but I'd rather be correct than fast.
I ended up subclassing the Catalyst::Dispatcher to make
prepare_action match all the dispatch types attributes specified for
an action. This allowed me to move my dispatch logic out of action
classes and into dispatch types where IMHO they belong.
I guess this would be a special kind of controller base class?
yep.
I should really take the time out to do a deep dive on Catalyst
so I can sort out its taxonomy in my head and hack out some
actual code?
yep.
Almost all my free time comes in 5-15 minute spans of time, or at the
expense of sleep. This is something I'd like to work on further, but
I just don't see the time being available any time soon. I'm envious
of you folks with enough time on your hands to dig in deep and
actually do something ;)
cheers,
Garrett