(Note that this discussion is getting rather dense. I suggest reading my reply all the way through befor responding to individual points. :)

On Jun 17, 2009, at 6:42 PM, Sergey Schetinin wrote:

On 2009-06-17, Jim Fulton <j...@zope.com> wrote:
On Jun 16, 2009, at 11:02 AM, Sergey Schetinin wrote:
...
indeed there are quite a few
frameworks / components that do this thing and I kind of don't get why
people want to write their apps that way. I wonder if Jim or anyone
else could explain the rationale behind all these URL routing
libraries. Nobody minds calling functions from other functions --
that's basics of programming, but for some reason URL dispatching is
seen as something different. Why?

This is not a criticism, I just really would like to understand this.



Fair enough. I'm not sure I understand your question. You need some way of mapping URLs onto Python objects that handle them. You can do this on a
case by case basis by inspecting a URL and doing some sort of ad hoc
dispatch in your application. Is that what you mean by "calling functions from other functions"? I've found it useful to have a standard mechanism for this that you can use over and over without reinventing it each time.

I guess didn't state my question properly, sorry. Let me explain what
I meant by "calling functions" analogy. My point is that when we
define a piece of functionality (as a function, class or whatever) we
don't say where to use it. I mean, we may define functions as "take
data from a this argument, process and return" and it's up to the
caller to pass that data into the function, function doesn't say where
that should come from or where in the rest of code should its body be
injected or anything like that. So function is a definition of
functionality and it is being called from somewhere else, the called
should know as little as possible about the caller and its place
relative to other calls its caller makes. At least that seems to be
the advice for good software design.

But software still lives in a namespace. You usually assign a function a name in a module or package. It often depends on other functionality being available under specific names. In web applications, we often need to know where other components are in the URL space. OTOH, often a function doesn't depend on it's name and you feel that a web application shouldn't care about it's URL. I get that. :)

When considering webapps and what urls they should handle it seems
like the same should apply -- webapps define contained blocks of
functionality and the task of placing them somewhere in URL-space
belongs to the "caller" which in this case would be a configuration or
serving script or, most often, a parent application.

OK, so you expect there to be a URL mapping, typically accomplished via some configuration mechanism outside the code. Most routing systems either require or allow this.

Sure, this
requires inspecting the URL, or as you said, "ad-hoc dispatching". I
think that misrepresents this approach because all it boils down to is
a series of if's, maybe a dictionary lookup and possibly regexp
matching is some cases (I personally never had to use that for URL
dispatch though). If we were to look at a similar approach in a
different context, I don't think it would be fair to call a series of
if/elifs "ad-hoc logic", so it's the same thing here.

I wasn't trying to represent what you said. I was just guessing at what you said. So you don't mind routing systems that are configured through routing tables outside the code. (?)

But let's go back to bobo, I can see how URL paths derived from file
and function names are nice and make sense, but I'm not as thrilled
with declaring the app path in a decorator. When looking at it from
the perspective of "caller defines when and how the subroutine is
called" I see that the entire (and very useful) level of abstraction
is gone -- the application path is defined right where the application
itself is defined. It's almost like declaring a piece of code and
saying "just inject this into file X at line Y" -- not pretty.

Again, I get that you want to separate URL from the code, but I don't agree with your analogy. This may not matter.

Something to note is that the paths used in bobo are often not absolute. If you use subroutes, http://bobo.digicool.com/index.html#subroutes , then the paths used will be relative to a position in a URL tree. In the referenced section, the paths in the Document and Folder resources are relative to the URLs used to access a document or folder.

An innovation in bobo, I think, is that it combines routes and traversal ("URL Dispatch" and traversal in http://docs.repoze.org/bfg/narr/urlmapping.html#differences-between-traversal-and-url-dispatch)


However, I have to admit, that if taken as an iterative improvement
over file/function name it looks very reasonable.

I'm not sure what you're referring to here.


In the original bobo (aka "python object publisher") that I wrote in '96, I mapped URLs onto object names in modules. Later, I extended this to use
object keys and this grew into a traversal model.  There were some
difficulties with this approach:

- I needed some way to decide which objects should be URL accessible. This
led to some less than optimal rules.

- The traversal model mapped well onto an object database, but not so well
onto relational models.

Many people have taken the approach of providing an explicit separate (from code) mechanism of mapping URLs onto their Python objects. Usually, this
involves having a table mapping URL patterns of some sort onto object
identifiers. I like explicit. :)

I like explicit too, and I like decoupled as well :) By giving up the
"manual" dispatching to some libraries people seem to dig themselves a
hole without even realizing it. There's so little code saved by doing
this, that I don't get it -- some of very useful features are given up
and it doesn't look like a tradeoff -- just giving control up without
a reason. ISTM that the reason is that this "manual dispatch" thing
seems more complex than it is in reality.

Nothing is given up. You can still configure paths externally if you want. (I'll have more to say on this below.)

To some extent, various routing libraries make sense because they
provide some level of extensibility, you know, like generic functions
vs. series of ifs. But given how they are used -- one global routing
object usually -- the need for that extensibility wouldn't be there if
not this initial design.

I don't understand what extensibility you're referring to here or if this has anything to do with your objection to specifying paths in the code.

Note that bobo doesn't require a global routing object. Bobo provides various ways of knitting URL trees together by having resources invoke other resources, as is done in the document-tree example referenced above.

In my view, this kind of routing also has the same flaw as the one I
see in bobo -- tight coupling. Apps know exactly what arguments they
want to get

I'm confused. Generally, Python functions know what arguments they want to get. What does this have to do with routing?

and those are directly "plugged" into data output of path
pattern used in the URL router.

Sorry, I can't parse this. :)

So basically there's a way to do dispatch with things like URLMap from
Paste and other similarly minimal dispatch mechanisms that just plug
one into another any way you wish and effortlessly and they are pretty
much extensible as it gets -- they can be updated from anywhere in
code.

Can you explain how you see this as different from:
http://bobo.digicool.com/more.html#configured-routes
?


This is a very simple alternative to the routing libraries that
I don't see used much. At the same time the problems with the popular,
routing approach make people write more and more of those hoping to
fix the problems that are actually inherent to the design. IMO anyway.

I still don't understand what you perceive these inherent problems to be.


On Jun 17, 2009, at 9:55 PM, Sergey Schetinin wrote:

On 2009-06-18, Aaron Watters <arw1...@yahoo.com> wrote:



--- On Wed, 6/17/09, Sergey Schetinin <mal...@gmail.com> wrote:

When considering webapps and what urls they should handle
it seems
like the same should apply -- webapps define contained
blocks of
functionality and the task of placing them somewhere in
URL-space
belongs to the "caller" which in this case would be a
configuration or
serving script or, most often, a parent application.


So you seem to be suggesting that a web component
should not be aware of its URL in the same sense
that an object is not aware of
its variable name in the scope of the application
that is using the object.  Is that right?

In particular you should be able to assign a
component to any URL in the same sense that you
can give an object any name.  You should also
be able to build relocatable URL trees which can
be "mounted" anywhere in the "calling" application
suite.  Do I catch your meaning correctly?

Spot on.

It's not clear to
me whether Bobo allows or disallows this

It does.

http://bobo.digicool.com/more.html#configured-routes

Generally, I think "allowing" it is not enough, I'd prefer it to be
*expected*, not just supported.

To some degree, this is the approach that Zope 3 took, It (strongly) encourages you to separate application implementation from configuration. This was motivated by a well-intentioned desire for the kind of flexibility I think you're advocating. The result was elegant but hard to deal with. I think it's great to have this flexibility when you need it, but in my experience, 99% of web applications don't need this sort of flexibility and the methods needed to support the flexibility become a tax.

My design for bobo is based on the assumption that most people don't need a lot of flexibility while some do, where the former is the common case. It tries to make simple applications very easy to create, without making it hard to address more complex requirements. I feel good about bobo's ability to deal with simple applications. Time will tell if it accommodates more complex applications. :)

This discussion falls into the larger debate of configuration vs convention and explicit vs implicit. I tend to prefer explicit, but am wary of systems that require a lot of configuration (having built one :). Most systems try to strike some balance, as does bobo.

Jim

--
Jim Fulton
Zope Corporation


_______________________________________________
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com

Reply via email to