On Apr 2, 2006, at 8:13 AM, Kendall Clark wrote:

> Actually I don't think this change would affect URL generation *at
> all*. HTTP methods have nothing to do with URL generation, and a
> route with a post or with a get method on the same URL would generate
> the same URL. I can't see any change.

Routes are searched to see if they can be used during URL generation.  
If you have a route that requires a http_method of POST, then that  
would be a valid generated URL *if* you were using url_for within a  
<form action=.... method="POST"> call. It would *not* be a valid URL  
to generate if you were merely making a link. This is what I mean  
when I say that url_for will need to be context aware to generate URL's.

>> Rather than trying to make Routes cope with these increasingly  
>> complex
>> situations, and the even more difficult task of having url_for become
>> aware of the context its generating a URL in....
>
> Well, again, this request wouldn't change url_for at all. The HTTP
> method is *not* part of a URL. It is part of a web request, but
> that's not really what url_for is for (and if someone is using it
> that way, then they need code like this:

url_for is for generating URL's, based on the Routes that are  
defined. If some Routes are valid only for specific http_methods,  
then knowing which http_method is being used during generation is  
absolutely important.

>> If you use this controller to inherit from, the controller will first
>> attempt to use a action called action_METHOD. So if you have
>> instances_POST, it will be used during a post, etc. Or you could
>> switch
>> it around, I kind of like it tailing since it would be easier to
>> scan a
>> controller with many methods visually.
>
> Eh, that's an ugly hack, dispatching based on the name of the method.
> Other frameworks do this, but I don't think it scales well at all.
> For example, in Python, this approaches makes it really hard to build
> any kind of metaprogramming or code generation support (since it's
> not at all easy to do this kind of method name introspectiony stuff
> in Python, w/out resorting to ugly string hacking, etc.)

Odd, I consider having to write 2 routes for 2 http methods to be  
quite ugly. Consider, with my approach, you could have a single  
Route, dispatch to 4 different actions depending on the http method,  
merely by adding a method action_GET, action_POST, etc. With your  
approach, you not only have to have those 4 actions, you have to have  
3 more routes as well.

Imagine 2 dozen different actions with 4 http method toggles each.  
Your proposal requires a Route for each, that's 8 DOZEN Routes. Ouch!  
The controller method I mention requires none of that heavy  
repetition. How is that an ugly hack compared to the incredible  
amount of Routes you need to write for every http_method?

> No. It would handle my case (which is really "the REST case", nothing
> specific about my app), but it wouldn't handle it at all *well*.

I would consider it to handle it better than writing dozens of Routes  
to match every http method.

> Well, that's the whole point -- which HTTP method is used to request
> a URI is an essential part of routing or dispatching that request to
> the controller that is supposed to handle it. Which suggests that
> Routes should recognize it.

Routes is URL recognition and generation, doing HTTP method checks is  
outside its current scope. Routes does not do dispatching, nor does  
it have much of a concept of controller really. Routes merely  
recognizes a URL, and returns a dict if it does. The framework then  
decides what to do with the results, and the framework dispatches.

> So, what does Routes do?
>
> 1. connects web requests to Python code (to Pylons controllers &
> actions) to handle the request
> 2. generates URIs (strings), not web requests.

As I mentioned, it doesn't actually connect web requests to code.  
This is what Pylons BaseController and the Pylons resolver system  
does, based on the results of what Routes tells it. The decision  
about how to dispatch is not in Routes, its in the BaseController and  
the Pylons resolver. This is why I proposed to extend the  
BaseController, since thats *already* one of the points of dispatch.

> A web request is an HTTP method plus a URL, essentially. (Okay,
> there's an HTTP version and some optional and required HTTP headers,
> but no one's suggesting or wants any of *that* packed into routes.)
>
> Routes should handle web requests, not just URL fragments, when it's
> routing requests to controllers & actions. Especially since it wants
> to be RESTful. :>

Yes, but the problem is that if its recognizing web requests, but  
cannot generate web requests, there's a bit of a problem. This is  
because those Routes which are used for recognizing are the same ones  
used to generate. If those Routes are now recognizing web requests,  
how are they to be utilized properly to create URL's?

I considered Routes RESTful because it gives you that ability should  
you choose it. Routes was never intended to do dispatch, just URL  
recognition. If you want to dispatch in a RESTful manner based off  
the URL generation, that should go in dispatch code. In Pylons,  
dispatch code is in the Pylons BaseController and Resolver, thus it  
is the only logical solution to extend one of those to dispatch  
appropriately based on the web request. This is how Pylons works at  
least.

Consider that in Pylons, it is intentional that the method in your  
controller is never actually called. Your controller is called, with  
the action passed in, and the *default* behavior is to pull the  
method by that name and call it. This is left like this intentionally  
so that its easy to extend *how* your actions are called within a  
controller. It's intentionally designed in this way to allow REST and  
other various custom dispatch schemes (XMLRPC, etc.) within a  
controller.

Given that I designed it in this way, why wouldn't it make sense to  
have a RESTful controller that dispatches appropriately?

> But it wouldn't break generation at all. Generation just creates
> strings. Strings that don't have anything to do with HTTP methods.
> This suggestion wouldn't change generation in the slightest sense.

Since the suggestion creates Routes that may only be valid based on  
HTTP method, that affects generation because those same Routes are  
searched during generation attempts.

> Well, if it comes to that, I'd rather write if-switches to dispatch
> to (essentially) private actions, rather than do the method-name
> hack. Sorry, but the method-name hack is *really* ugly, IMO. ;>

I'm not sure why you'd consider it an ugly hack. It's only slightly  
different than the current dispatch scheme that the BaseController  
uses. Have you looked at the source code for the current BaseController?

> Explicit (put the method in the route) is better than implicit
> (method-name hack).

Agreed, unless it results in so much additional work that people are  
ready to jump ship. Your suggestion results in a Route for every http  
method for every action. That totally violates DRY by creating huge  
amounts of repetition. The RESTController approach does not result in  
dozens or hundreds of additional Routes, and instead programmatically  
handles dispatch based on the method. This results in significantly  
less effort for a developer, less time spent writing Routes for every  
action and http_method, and more time writing their code that handles  
it.

> And, I'll add another one of my own that I think is just as good/
> important:
>
> Declarative (declare the http method in the route, and let some
> infrastructure code act on that declaration at run-time or at web req
> time) is better than procedural (lots of unnecessary if-then switches
> in application code).

Since the infrastructure currently handles dispatch, why should the  
*pure* URL recognizer be extended to handle HTTP method in such a  
labor-intensive style? What's so ugly about killing all this  
repetition and extra work by programmatically dispatching to the  
action by including the HTTP method?

Please consider in your original rationale:

> 2. it makes good sense re: code... In an app I have, I want a
> particular URL to do one thing when it's GET'd and something else
> when it's POST'd to, and I'd like to dispatch to a different action
> of the same controller in each case, and I'd like that to be handled
> in routes:

This is *exactly* why the controller is called as it is. So that it  
can be extended to dispatch differently within a controller based on  
your needs. Why is it ugly to extend the existing action dispatch?

I would like to have a solution that makes you happy, but I'm  
extremely wary of this suggestion in its current form due to the  
amount of Routing code one will need to write. Do you have any other  
thoughts on how to reduce that?

Cheers,
Ben

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [EMAIL PROTECTED]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss
-~----------~----~----~----~------~----~------~--~---

Reply via email to