WSGI规范(PEP 3333) 第四部分(常见问题)

这是规范的最后一部分:常见问题。

原规范还有《建议、讨论中》、《知识》、《参考文献》。由于和规范不太相关,就不作翻译了。


1. 为什么 environ 必须用字典表示?用字典子类表示会出现什么问题?

使用字典的理由是,可以最大化服务器之间的可移植性。替换方案是定义一个字典的子类作为标准的、可移植的接口,其所有方法是 dict 类的方法的子集。然而,实际上,大部分服务器会找到一个满足需要的字典即可,因此框架作者们渐渐发现它们希望找到一个可用完整字典特性的字典实现,因为它们通常会需要。但如果某个服务器选择不适用字典表示 environ,就会出现互操作性问题,尽管服务器会尽量和规范保持一致。因此。为了简化规范和保持一致性,字典就变得非常必要了。

这并不表示服务器或者框架的开发者们不能增加其他内容(如在 environ 里自定义一些变量)。这恰恰是规范推荐的方法。


2. 为什么你可以调用 write(),也可以使用 yield 字符串/return迭代对象?使用其中之一不就够了?

如果只支持迭代方法,当前的一些使用 push 方法的框架就无法兼容;但是如果我们只通过 write() 支持 push 方法,服务器性能则因为传输大文件而下降(工作线程直到当前输出完成之后,才能开始处理新请求)。因而,我们做出一点妥协,应用框架就可以支持者两种方法;相应地,服务器开发者则要比只支持 push方法多做一点工作。


3. close()有什么用?

当应用对象完成写操作后,通过 try/finally 块,应用对象可以确保相关资源得到释放。但是,如果应用返回的是迭代对象,相关资源要等迭代对象被 gc 回收之后才会释放。而 close()则使应用对象在请求处理完成之后,释放相关资源(调用 close()释放资源)。这也是向前兼容的,支持生成器内部的 try/finally 块。


4. 为什么 WSGI 这么低级(译者注:CGI 变量相对于应用中的对象是低级的)?我想用高级特性,如 cookies、sessions、持久化。。。

WSGI 不是另一个 Python web 框架。它仅仅是一种让框架和 web 服务器通信的方式,反过来也成立。你想要的这些特性应该由框架提供。并且,如果让你自己创建 WSGI 应用对象,你应该能够在多数支持 WSGI 的服务器上运行它。有些服务器会在 environ 字典中存放额外的信息;去看看服务器的文档吧。当然,使用了这些扩展信息的应用很可能不兼容其他支持 WSGI 的服务器。


5. 为什么使用 CGI 变量而不是 HTTP 头?为什么将他们和 WSGI 定义的变量混用?

相对 CGI 规范,许多现存的 web 框架是沉重的;而现存的 web 服务器则擅长生成 CGI 变量。Many existing web frameworks are built heavily upon the CGI spec, and existing web servers know how to generate CGI variables. 相反,另一种方法,

In contrast, alternative ways of representing inbound HTTP information are fragmented and lack market share. Thus, using the CGI "standard" seems like a good way to leverage existing implementations. As for mixing them with WSGI variables, separating them would just require two dictionary arguments to be passed around, while providing no real benefits.


6. status 是什么?能不能用数字200代替 "200 OK"呢?

用200代替"200 OK"会使得服务器/网关复杂化,因为这会要求它们维护一张数字和消息映射表。然而,对应用或者框架作者来说,输入消息文本和相应的状态码是容易的。现存的框架一般已经有这张表,所以,让应用/框架来负责这件事,要比服务器/网关要好。


7. 为什么 wsgi.run_once 不能保证只运行应用一次?

Because it's merely a suggestion to the application that it should "rig for infrequent running". This is intended for application frameworks that have multiple modes of operation for caching, sessions, and so forth. In a "multiple run" mode, such frameworks may preload caches, and may not write e.g. logs or session data to disk after each request. In "single run" mode, such frameworks avoid preloading and flush all necessary writes after each request.

However, in order to test an application or framework to verify correct operation in the latter mode, it may be necessary (or at least expedient) to invoke it more than once. Therefore, an application should not assume that it will definitely not be run again, just because it is called with wsgi.run_once set to True .


8. Feature X (dictionaries, callables, etc.) are ugly for use in application code; why don't we use objects instead?

All of these implementation choices of WSGI are specifically intended to decouple features from one another; recombining these features into encapsulated objects makes it somewhat harder to write servers or gateways, and an order of magnitude harder to write middleware that replaces or modifies only small portions of the overall functionality.

In essence, middleware wants to have a "Chain of Responsibility" pattern, whereby it can act as a "handler" for some functions, while allowing others to remain unchanged. This is difficult to do with ordinary Python objects, if the interface is to remain extensible. For example, one must use __getattr__ or __getattribute__ overrides, to ensure that extensions (such as attributes defined by future WSGI versions) are passed through.

This type of code is notoriously difficult to get 100% correct, and few people will want to write it themselves. They will therefore copy other people's implementations, but fail to update them when the person they copied from corrects yet another corner case.

Further, this necessary boilerplate would be pure excise, a developer tax paid by middleware developers to support a slightly prettier API for application framework developers. But, application framework developers will typically only be updating one framework to support WSGI, and in a very limited part of their framework as a whole. It will likely be their first (and maybe their only) WSGI implementation, and thus they will likely implement with this specification ready to hand. Thus, the effort of making the API "prettier" with object attributes and suchlike would likely be wasted for this audience.

We encourage those who want a prettier (or otherwise improved) WSGI interface for use in direct web application programming (as opposed to web framework development) to develop APIs or frameworks that wrap WSGI for convenient use by application developers. In this way, WSGI can remain conveniently low-level for server and middleware authors, while not being "ugly" for application developers.


WSGI规范(PEP 3333) 第一部分(概述)

WSGI规范(PEP 3333) 第二部分(细节)

WSGI规范(PEP 3333) 第三部分(实现)

编辑于 2017-07-29

文章被以下专栏收录