12.8 总结

    我们介绍了用RESTful Web服务、wsgiref模块和multiprocessing模块传输和共享对象,这些技术架构都为对象状态表示的交互提供了支持。如果使用multiprocessing,那么pickle会作为它表示状态的方式。如果创建RESTful Web服务,必须选择使用哪些表示方式。在本章的例子中,我们只关注JSON,因为它被广泛应用而且实现非常简单。许多框架也会提供简单的XML实现。

    通过WSGI应用程序框架执行RESTful Web服务统一接收HTTP请求、反序列化对象、执行请求的功能、序列化结果并且提供响应的过程。由于WSGI应用程序的API简单、标准,因此我们可以很容易地创建复合应用程序和封装程序。我们经常通过封装的程序以一种简单、一致的方式处理安全性中身份验证的部分。

    我们还介绍了用multiprocessing将消息插入共享队列或者从共享队列中移除消息。使用消息队列的好处是我们可以避免并发更新共享对象所带来的锁问题。

    12.8.1 设计要素和折中方案

    我们也必须决定允许访问的对象粒度以及如何通过清晰的URI标识它们。如果使用大对象,很容易地就可以实现ACID属性。但是,在我们的应用程序的例子中,这也可能会导致下载或者上传太多数据。在一些情况下,我们需要提供不同的访问级别:支持ACID属性的大对象、当客户端应用程序请求数据的一个子集时用于快速响应的小对象。

    我们可以用multiprocessing模块实现更集中的处理过程,这种方式主要是为了在一个可信赖的主机或者多个主机的网络中创建高性能的处理管道。

    在某些情况下,我们会合并使用两种设计模式,这样RESTful的请求就会由multiprocessing管道处理。传统的使用了mod_wsgi插件的Web服务器(例如Apache HTTPD)可以用multiprocessing技术通过一个命名管道将请求从Apache的前端传递到WSGI应用程序的后台。

    12.8.2 模式演变

    当为RESTful服务开发公用的API时,我们必须注意模式演变的问题。如果我们修改了类的定义,那么要如何修改响应消息呢?如果为了与其他的程序兼容,必须修改外部的RESTful API,那么需要升级Python的Web服务来支持改变的API吗?

    通常,我们必须为API提供一个主要的发布版本号。它可能显式地作为路径的一部分,或者通过包含在POSTPUTDELETE请求中的数据字段隐式地提供。

    我们需要区别对待不会修改URI路径或者响应的情况和会修改URI或者响应的情况。功能上的轻度改变不会影响URI或者响应的结构。

    改变URI或者响应的结构可能会影响正在运行的应用程序,这些属于主要改变。让应用程序仍然可以正常工作的一种方法是通过模式升级在 URI 路径中包含版本号。例如,/roulette_2/wheel/指定了roulette服务器的第2个发布版本。

    12.8.3 应用程序软件层次

    由于使用sqlite3时,应用程序会变得相对复杂,我们的应用程序软件必须层次化得更合理。对于一个REST客户端,我们可以看作一个多层的软件架构。

    当我们创建RESTful服务器时,表示层会被极大地简化。它被缩减为只需要处理基本的请求-响应。它解析URI然后用JSON或者XML文档(或者一些其他的表示方式)响应客户端。这层应该被简化为一个封装了低层功能的精简的RESTful外观。

    在一些复杂的例子中,用户浏览的最前端的应用程序包含的数据来自多个不同的数据源。集成来自不同数据源的数据的一种简单方法是将每个数据源封装在一个RESTful API中,这为我们访问不同的数据源提供了统一的接口。这样的设计让我们可以编写以统一的方式收集这些不同源头的数据。

    12.8.4 展望

    在下一章中,我们将介绍如何使用持久化技术处理配置文件。一个可以人工修改的文件是可配置数据的主要要求。如果我们使用一个大家都很熟悉的持久化模块,那么我们只需编写很少的代码,应用程序就可以解析并验证配置数据。