mahmoud / clastic

🏔️ A functional web framework that streamlines explicit development practices while eliminating global state.
https://python-clastic.readthedocs.io/en/latest/
Other
158 stars 19 forks source link

Can't figure out how to build URLs from Request #7

Open alecthomas opened 10 years ago

alecthomas commented 10 years ago

Hi,

I can't seem to find a way to build URLs from a request. I see that the adapter is built inside Application.respond() but it doesn't seem to be exposed. I also can't figure out an alternative way to build it.

Thanks, Alec

PS. I have been looking for a Python web framework like clastic FOREVER. The global state in your typical Python framework drives me absolutely nuts. So thank you :)

mahmoud commented 10 years ago

Oh my, an organic user, things just got trill.

So I polled some Werkzeug users around me and I didn't have very many takers/users of most of Werkzeug's routing abstractions. In fact, it's caused some major issues, like #3. (In further fact, I've got some branches with some lighter-weight routing designs I've been putting together.)

Specifically when you say building URLs, do you mean like treating them as templates, sort of like "reverse()"? Or some form of simple redirect? Because you can definitely access the current URL via the Request object. So, one or two concrete use cases would be useful. I'd also be interested in your opinions on Werkzeug's routing abstractions. Much/most of the complexity seems to be in support of rather passe features like dynamic subdomain routing (i.e., alecthomas.mysite.com), which could be better achieved via web server rewriting, but probably shouldn't be done at all (security issues, cookies).

Mahmoud

mahmoud commented 10 years ago

PS Voluptuous is pretty awesome. A form-parsing middleware based on it has been on my TODO pretty much since day 1. So also thanks ;)

alecthomas commented 10 years ago

Sorry, yeah, I am referring to reconstructing a URL from a Route. Equivalent to Flask's url_for(endpoint, **values).

FWIW, I don't use any complex features of Werkzeug's routing at all, so I wouldn't miss them at all.

Glad you like Voluptuous!

mahmoud commented 10 years ago

Ah, yes, I've frequently had this on my mind. There is a caveat though, while that would be possible/straightforward to add in, with Clastic it's very easy to have multiple Routes using the same endpoint function. An easy example would be something along the lines of /job/<id>/ and /job/<id>/json/, the former which returns HTML, the latter JSON, but both point at the same endpoint function.

Anyways, I've also found it kind of confusing because while Clastic enables this sort of collision, it's not unique in the slightest. See this StackOverflow question, for instance (don't get DPR'd). And then if we get into naming URLs, well, now you've got two conventions to manage (URLs and URL names). In my Django days I saw way too many templates taken down because of a missed urlresolvers.reverse() call.

That said, it probably wouldn't be a big deal to add a caveat-emptor url_for(), if we can answer a couple questions. Here's what I'm thinking:

def get_foo(_application, foo_id):
    return redirect(_application.get_url_for(get_other, bar_id=foo_id))

def get_other(bar_id):
    return 'result'

As you can see, the Application would fulfill the role of URL map/adapter, and facilitates these sorts of lookups. Now, the question is: if there are multiple URLs with that endpoint, would you rather I raise an exception or just return the first? Routes could also be name-able, but is it worth the syntax overhead?

alecthomas commented 10 years ago

Yeah, in Flask I have always been rigorous about using IDs everywhere and using those in url_for. It works well, but you do have to be a bit more disciplined.