Routes pattern and args / query strings

74 views
Skip to first unread message

Louis Amon

unread,
Feb 25, 2015, 6:18:02 AM2/25/15
to web...@googlegroups.com
I'm opening this thread to discuss pattern-based routing and especially the handling of args and vars in an incoming URL.


Based on the doc, you can use a simplified syntax in pattern-based routes to avoid struggling with regular expressions:
('/new_name/$anything', '/app/controller/function$anything')
If you do so however, the URL /new_name/args would be reachable but /new_name wouldn't and neither would /new_name?this=that.

One solution I found to this problem is to write instead:
('/s$anything', '/myapp/default/search$anything')
(notice there is no / before the $)

I changed new_name to s in order to illustrate another issue : if you use $anything like I just did, you might have conflicts between URLs depending on where in the list (routes_in) your put this specific rule.

For instance, routing /static would be problematic with a /s$anything rule.


In fact, what you really need to route is much less than /s$anything. As far as I can see there are 4 cases:
1. /s
2. /s?vars
3. /s/args
4. /s/args?vars

I guess writing explicity these 4 rules would do the trick much better than /s$anything, thus avoiding the conflict with /static... but it could also become very bulky if you have to write 4 rules for each URL.


Is there a clean way to do this using the pattern-based system ?

Anthony

unread,
Feb 25, 2015, 7:03:05 AM2/25/15
to web...@googlegroups.com
In some cases, $anything isn't powerful enough, and you need to use regular expressions.

Anyway, the rules are processed in order, so you should be able to include a rule mapping static to static, and then include the /s$anything rule (which won't be matched to "static" because the static rule will already have matched).

Anthony

Louis Amon

unread,
Feb 25, 2015, 7:54:36 AM2/25/15
to web...@googlegroups.com
Anyway, the rules are processed in order, so you should be able to include a rule mapping static to static, and then include the /s$anything rule (which won't be matched to "static" because the static rule will already have matched).

That’s actually what I ended up doing, but it isn’t something you can rely on in a big project…

In some cases, $anything isn't powerful enough, and you need to use regular expressions.

I was hoping there would be an alternative, but I guess regular expressions are indeed the only option to do things properly.



--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/sMPkRPjZWrg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anthony

unread,
Feb 25, 2015, 2:57:27 PM2/25/15
to
On Wednesday, February 25, 2015 at 7:54:36 AM UTC-5, Louis Amon wrote:
Anyway, the rules are processed in order, so you should be able to include a rule mapping static to static, and then include the /s$anything rule (which won't be matched to "static" because the static rule will already have matched).

That’s actually what I ended up doing, but it isn’t something you can rely on in a big project…

Why not?
 
In some cases, $anything isn't powerful enough, and you need to use regular expressions.

I was hoping there would be an alternative, but I guess regular expressions are indeed the only option to do things properly.

Did you have a particular API in mind? The parameter-based system is designed to be much simpler while covering the most common use cases, but if you want something highly customized, there will inevitably be some complexity to the rules you set up.

Anthony

Niphlod

unread,
Feb 25, 2015, 3:39:29 PM2/25/15
to web...@googlegroups.com
BTW... just to synchronize ourself, what the book gives as an example is

('/new_name/$anything', '/app/controller/function/$anything')

mind the / part . This is the only safe way to do what people usually want to "translate", that is the app/c/f part, while leaving args and vars untouched. You can work around using something like you suggested, but you already faced what the developers faced: the utter and complete disaster in mapping what comes in .

Of course (if you think to the method a piece of code would convert this to a regex) this just maps whatever is coming AFTER /newname/ and not what reaches /newname (again, mind the lack of the last /).

Frankly, I'm a bit scared to suggest that your issue (i.e. being accustomed on how web2py treats incoming urls in without arguments, which is that calling /a/c/f is the same as /a/c/f/) can be easily solved by

('/new_name', '/app/controller/function')



Louis Amon

unread,
Feb 26, 2015, 3:35:50 AM2/26/15
to web...@googlegroups.com
That’s actually what I ended up doing, but it isn’t something you can rely on in a big project…

Why not?

Because you’d have to document very clearly the fact that some specific rules need to be organized in a precise order among the list.
If you have hundreds of URLs managed in your routes.py and if 10 of them need to be organized in specific orders then if you want to add an URL you need a very clear view of exactly where you need to put the rule to match it.

Now imagine an intern takes over the routing… this whole order-based routing would be an epic mess.

I was hoping there would be an alternative, but I guess regular expressions are indeed the only option to do things properly.

Did you have a particular API in mind? The parameter-based system is designed to be much simpler while cover the most common use cases, but if you want something highly customized, there will inevitably be some complexity to the rules you set up.

I was thinking about something like $args or $vars that would be pre-coded with the right regex to match one or no args and/or a query string.


Le 25 févr. 2015 à 20:57, Anthony <abas...@gmail.com> a écrit :

On Wednesday, February 25, 2015 at 7:54:36 AM UTC-5, Louis Amon wrote:
Anyway, the rules are processed in order, so you should be able to include a rule mapping static to static, and then include the /s$anything rule (which won't be matched to "static" because the static rule will already have matched).

That’s actually what I ended up doing, but it isn’t something you can rely on in a big project…

Why not?
 
In some cases, $anything isn't powerful enough, and you need to use regular expressions.

I was hoping there would be an alternative, but I guess regular expressions are indeed the only option to do things properly.

Did you have a particular API in mind? The parameter-based system is designed to be much simpler while cover the most common use cases, but if you want something highly customized, there will inevitably be some complexity to the rules you set up.

Anthony

Anthony

unread,
Feb 26, 2015, 8:51:51 AM2/26/15
to
On Thursday, February 26, 2015 at 3:35:50 AM UTC-5, Louis Amon wrote:
That’s actually what I ended up doing, but it isn’t something you can rely on in a big project…

Why not?

Because you’d have to document very clearly the fact that some specific rules need to be organized in a precise order among the list.
If you have hundreds of URLs managed in your routes.py and if 10 of them need to be organized in specific orders then if you want to add an URL you need a very clear view of exactly where you need to put the rule to match it.

Now imagine an intern takes over the routing… this whole order-based routing would be an epic mess.

That's entirely a function of the nature of your routing scheme and would apply to any pattern based system. An alternative is to come up with much more complicated regexes, but you still have the problem of needing to update the regexes as your app grows/changes. This is the advantage of keeping the routing more simple and straightforward (i.e., sticking with the default routing, plus some of the tweaks allowed by the parameter based system). When you introduce a unique and idiosyncratic routing scheme, you are creating complexity that must then be managed.

Note, if your routing scheme can be systemitized, you could write a function that automatically generates the necessary patterns based on a limited set of inputs. The routes.py file is just Python code that gets executed, so you can use any means to generate routes_in and routes_out.
I was hoping there would be an alternative, but I guess regular expressions are indeed the only option to do things properly.

Did you have a particular API in mind? The parameter-based system is designed to be much simpler while cover the most common use cases, but if you want something highly customized, there will inevitably be some complexity to the rules you set up.

I was thinking about something like $args or $vars that would be pre-coded with the right regex to match one or no args and/or a query string.

It would at least be helpful to document some examples of these patterns. Note, once you have the relevant regex, you can assign it to a variable in routes.py and re-use it.

Anthony
Reply all
Reply to author
Forward
0 new messages