WSGI中间件是有害的

来源:互联网 发布:socket编程视频教程c 编辑:程序博客网 时间:2024/05/01 05:26

Saturday, February 10, 2007

WSGI中间件是有害的(WSGI Middleware Considered Harmful)

 

<rant mode="on" type="get-off-my-lawn-you-crazy-younguns">

WSGI中间件对你的API“健康”是有害的。这是我说过的

我关于WSGI中间件的那个问题虽然实际不是出在WSGI本身,但看起来很多人认为问题是出在WSGI中间件。

我所写的PEP 333其中一部分讨论了框架也许会在未来某一天成为中间件,遗憾的是,我在那里面走的路线已经造就了一个完整的思想学派,就是把这个观点看成其意味着中间件应该被用来创建扩展WSGI本身的协议!

更确切的说,人们似乎认为如果你通过中间件提供一个服务,你就不得不为那个服务将API嵌入进WSGI环境中。很明显,他们是认为由于WSGI将很多东西都放到了环境中,并且由于服务器允许通过环境来提供扩展的APIs,那么便理应存在中间件,其唯一目的就是将API放到环境中。

然而,这没有什么实际意义。如果你的应用程序需要那个API出现,那么它便不再是中间件!

你知道,中间件是为了使应用程序拥有额外的行为而存在的。如果你不能随意决定是否将它放到程序的前面,它就不再是中间件了。而是程序的一部分

而如果它是程序的一部分,试图将它放到程序的外面无疑是浪费时间!

同时,你为了使用它还要不得不将那些东西放到环境的外面,做一些类似environ['some.session.service'].whatever()的赌注,目的是要能够像omeSessionService(environ).whatever()一样写得更清晰,还不要求你在你的程序对象的上面堆砌一大堆所谓的“中间件”。

所以,现在就请停止做这种愚蠢的事。如果你禁不住诱惑使用中间件将某些东西放到了环境中,使得过后程序可以通过对环境的直接访问将其分离开来,请不要这样做

取而代之的是编写可以完成任何需要完成的库函数或类,它们还(或许)可以使用特定库(library-specific)的keys数据存储到环境中。不要让你的库的用户们直接访问这些keys,而是用给他们可以利用这个私有数据作一些有用的事情的函数或方法。

不要让用户将他们的程序包装在你所谓的“中间件”中,那时候一个回调(callback)或装饰器(decorator)会做那个工作。的确,技术上讲那仍是中间件,但实际上使用通过一个装饰器或将回调传递给库函数来实现的中间件要比在服务器部署层配置一个复杂的中间件栈(middleware stack)简单的多。

保留这类真正的中间件例如,部署deployment)中间件,作为特定针对哪个应用程序的工具。还有一些工具像测试器,调试器,日志记录器,代理,路由器,缓存和压缩器等等。

类似这样的有关部署栈(deployment-stack)中间件的正规的应用程序有很多很多,并且几乎无一例外那些工具都不关心他们是用在什么样程序上面,而应用程序也不知道它们的存在。

然而,从技术层面上当应用程序“中间件”讲成为WSGI中间件,它不应被强拉进部署栈(deployment stack)之中,在那里它会很难进行部署。光明正大地向你的用户提供一个真正API,让那个他们在其程序中能用上。

好的,这么做就足矣了。

</rant>

P.S. 避免将APIs当作中间件实现的另一个原因是,要想写出来一个正确的、兼容WSGI的中间件是极端困难的,而且在这期间非常容易做出些很的事情。要始终在中间件的两头使用wsgiref.validate来进行测试。这样,validator不但被包装(wrap)进了中间件本身,还包装进了中间件包装的程序!如果你不那样做,你将错过所有一致性(compliancebugs

P.P.S. 注意,这就意味着WSGI1.0无法实现让中间件“既简单又健壮”的目标。我对WSGI2.0有一些想法,其将彻底简化应用程序和中间件,但是以去掉无缓存数据流(unbuffered streaming)的write()可调用对象为代价的。我关于2.0的想法将允许WSGI1.0应用从一个2.0服务器调用(当然,使用2.x中间件),但是,若中间件使用greenlets、线程或一些其他的同步机制,write()操作只能被流化(streamed)。

下面来看看WSGI 2.0应用程序长什么样:

  

def simple_app(environ):

    
"""Simplest possible WSGI 2.0 application object"""

    
return (

        
'200 OK'

        [(
'Content-type','text/plain')],

        [
'Hello world! ']

    )

 

 

我将它作为一个练习留给读者,来体会一下通过使用这个方法所有事情(包括库、应用程序和中间件)是多么的简单。它是以将write()驱动的流程序(streaming applications)降格为得在另一个线程运行的“二等公民”为代价可不管怎样,他们已肯定是位于服务器(像Twisted)之下了。

 

 

(原文链接网址:http://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html

 
原创粉丝点击