[Web-SIG] Standardized configuration

Phillip J. Eby pje at telecommunity.com
Sun Jul 17 20:23:46 CEST 2005


At 03:28 AM 7/17/2005 -0500, Ian Bicking wrote:
>Phillip J. Eby wrote:
>>What I think you actually need is a way to create WSGI application 
>>objects with a "context" object.  The "context" object would have a 
>>method like "get_service(name)", and if it didn't find the service, it 
>>would ask its parent context, and so on, until there's no parent context 
>>to get it from.  The web server would provide a way to configure a root 
>>or default context.
>
>I guess I'm treating the request environment as that context.  I don't 
>really see the problem with that...?

It puts a layer in the request call stack for each service you want to 
offer, versus *no* layers for an arbitrary number of services.  It adds 
work to every request to put stuff into the environment, then take it out 
again, versus just getting what you want in the first place.


>In many cases, the middleware is modifying or watching the application's 
>output.  For instance, catching a 401 and turning that into the 
>appropriate login -- which might mean producing a 401, a redirect, a login 
>page via internal redirect, or whatever.

And that would be legitimate middleware, except I don't think that's what 
you really want for that use case.  What you want is an "authentication 
service" that you just call to say, "I need a login" and get the login 
information from, and return its return value so that it does 
start_response for you and sends the right output.

The difference is obliviousness; if you want to *wrap* an application not 
written to use WSGI services, then it makes sense to make it 
middleware.  If you're writing a new application, just have it use 
components instead of mocking up a 401 just so you can use the existing 
middleware.

Notice, by the way, that it's trivial to create middleware that detects the 
401 and then *invokes the service*.  So, it's more reusable to make 
services be services, and middleware be wrappers to apply services to 
oblivious applications.


>I guess you could make one Uber Middleware that could handle the services' 
>needs to rewrite output, watch for errors and finalize resources, etc.

Um, it's called a library of functions.  :)  WSGI was designed to make it 
easy to use library calls to do stuff.  If you don't need the 
obliviousness, then library calls (or service calls) are the Obvious Way To 
Do It.


>   This isn't unreasonable, and I've kind of expected one to evolve at 
> some point.  But you'll have to say more to get me to see how "services" 
> is a better way to manage this.

I'm saying that middleware can use services, and applications can use 
services.  Making applications *have to* use middleware in order to use the 
services is wasteful of both computer time and developer brainpower.  Just 
let them use services directly when the situation calls for it, and you can 
always write middleware to use the services when you encounter the 
occasional (and ever-rarer with time) oblivious application.


>>Really, the only stuff that actually needs to be middleware, is stuff 
>>that wraps an *oblivious* application; i.e., the application doesn't know 
>>it's there.  If it's a service the application uses, then it makes more 
>>sense to create a service management mechanism for configuration and 
>>deployment of WSGI applications.
>
>Applications always care about the things around them, so any convention 
>that middleware and applications be unaware of each other would rule out 
>most middleware.

Yes, exactly!  Now you understand me.  :)  If the application is what wants 
the service, let it just call the service.  Middleware is *overhead* in 
that case.


>>I hope this isn't too vague; I've been wanting to say something about 
>>this since I saw your blog post about doing transaction services in WSGI, 
>>as that was when I first understood why you were making everything into 
>>middleware.  (i.e., to create a poor man's substitute for "placeful" 
>>services and utilities as found in PEAK and Zope 3.)
>
>What do they provide that middleware does not?

Well, some services may be things the application needs only when it's 
being initially configured.  Or maybe the service is something like a 
scheduler that gives timed callbacks.  There are lots of non-per-request 
services that make sense, so forcing service access to be only through the 
environment makes for cruftier code, since you now have to keep track of 
whether you've been called before, and then do any setup during your first 
web hit.  For that matter, some service configuration might need to be 
dynamically determined, based on the application object requesting it.

But the main thing they provide that middleware does not is simplicity and 
ease of use.  I understand your desire to preserve the appearance of 
neutrality, but you are creating new web frameworks here, and making them 
ugly doesn't make them any less of a framework.  :)

What's worse is that by tying the service access mechanism to the request 
environment, you're effectively locking out frameworks like PEAK and Zope 3 
from being able to play, and that goes against (IMO) the goals of WSGI, 
which is to get more and more frameworks to be able to play, and give them 
*incentive* to merge and dissolve and be assimilated into the primordial 
soup of WSGI-based integration, or at least to be competitors for various 
implementation/use case niches in the WSGI ecosystem.

See also my message to Chris just now about why a WSGI service spec can and 
should follow different rules of engagement than the WSGI spec did; it 
really isn't necessary to make services ugly for applications in order to 
make it easy for server implementors, as it was for the WSGI core spec.  In 
fact, the opposite condition applies: the service stack should make it easy 
and clean for applications to use WSGI services, because they're the things 
that will let them hide WSGI implementation details in the absence of an 
existing web framework.



More information about the Web-SIG mailing list