简明现代魔法 -> 软件架构技术 -> IBM 教程:Ajax 和 REST,Part 1
IBM 教程:Ajax 和 REST,Part 12010-02-08
服务器端 Web 应用程序因采用富应用程序模型和交付个性化内容而具备了融入式(immersive) 的特点,这种特点越突出,应用程序架构对 Web 架构风格 REST(Representational State Transfer)的违背就越多。这种违背会降低应用程序的可伸缩性,增加系统复杂性。通过与 REST 相互协调,Ajax 架构将使融入式 Web 应用程序消除这些负面影响,尽享 REST 那些出色的特性。
在短短 15 年中,World Wide Web 已经从一项研究实验成长为现代社会的技术支柱。最初发明 Web 的目的是使人们可以轻松发布和链接信息,现在它已经发展为软件应用程序的可行平台。但随着应用程序通过使用富应用程序模型和生成个性化内容而获得了更多的融入性,它们的架构对 Web 架构风格 REST(Representational State Transfer)的违背也越来越多。这种违背会降低应用程序的可伸缩性,增加系统复杂性。
新兴的 Ajax Web 客户机架构风格让融入式 Web 应用程序与 REST 架构风格协调一致。使它们可以尽享 REST 那些出色的特性,同时又消除了应用程序违背 REST 准则时带来的不良特性。本文将介绍为融入式 Web 应用程序成功结合 Ajax 和 REST 的方法与原因。
REST:Web 架构尽管 World Wide Web 是在数十年的相关研究基础上建立起来的,但它的有效诞生日期是 1990 年 12 月,当时 Tim Berners-Lee 完成了 Web 主要组件的工作原型:统一资源标识符(URI)、HTTP、HTML、浏览器和服务器。Web 被迅猛采用,远远超过了先驱者们的预期。在 Roy Fielding 最出名的系列文章中(请参看 参考资料),他描述了自己当时的心情:
“尽管对其成功感到兴奋不已,但是 Internet 开发者社区逐渐开始担心,Web 使用的这种快速增长,以及早期 HTTP 的 一些拙劣的网络特性,会快速压倒 Internet 基础设施所能承担的容量,从而导致突然的崩塌。”Fielding 和其他人对 Web 架构及其是否能够足以支持各种扩展和用法重新进行了审视。这种重新审视的有形结果包括更新诸如 URI 和 HTTP 之类的一些重要标准。这种重新审视还获得了一些无形但却非常有意义的结果:为超级媒体应用程序确定了一种新的架构风格,Fielding 将其命名为 REST(Representational State Transfer)。Fielding 断言,使用且符合 REST 设计约束的 Web 上部署的组件可以充分利用 Web 的有用特性。他还警告说,违背 REST 准则的 Web 组件都将无法利用这些优点。
“一种架构在设计时就应该考虑到一组特性,让它可以满足甚至超越系统的需求。忽略这些特性可能会导致后期变更干扰 整个架构,就像是使用一扇落地窗去取代承重墙会破坏整个建筑结构的可靠性。” —— Roy Fielding早期时,大部分 Web 站点和简单的 Web 应用程序实际上都是遵守 REST 准则的。但是随着融入式 Web 应用程序的日益普及,Web 应用程序架构逐渐开始背离 REST 准则了,此后因果循环,情况日益恶化。融入式服务器端 Web 架构的问题很难分析清楚,因为在使用这种架构风格的十年中,已经建立起这样一种信仰:这些问题都是 Web 应用程序架构所固有的。实际上,这并非是 Web 应用程序架构的问题。而是由服务器端 Web 应用程序架构风格所产生的问题。要打破这种偏见,我们来回顾一下整个架构是如何发展到现在这种状态的,这会很有帮助。我们将说明为什么在 Ajax 应用程序创建在商业上可行之后,过去接受的很多假设现在都不再成立了。
Web 应用程序的简史Berners-Lee 创造了 Web,最初是将 Web 作为研究人员远程共享文档和在文档之间创建简单链接以加速知识和思想传播的一种手段。然而,URI 标准的架构特征很快实现了除静态文件之外更多内容的共享。
提供静态文档的 Web 站点
Web 上最早的内容由一些静态 HTML 文档组成,其中有很多到其他静态文档的链接,如图 1 所示:
图 1. 提供静态文档的 Web 站点
REST 使静态文档的检索极其高效、可伸缩,这是因为它们可以根据 URI 和最后修改日期来轻松缓存。很快开发人员就超越了静态文档的领域,开始动态文档的提供。
早期的动态 Web 应用程序
Berners-Lee 和其他人设计了 URI 标准,为资源的统一唯一标识提供支持,同时使其表示(HTML、文本等)根据 Web 客户机(通常是 Web 浏览器)和 Web 服务器之间的协商结果而变化。由于 URI 将资源标识和资源的底层存储机制区分开来,因此 Web 开发人员可以创建一些程序,使之检查 URI 语法,并动态生成文档,将预先定义的 UI 元素和动态检索的数据(通常是从关系数据库中)合并在一起,如图 2 所示。尽管这些文档是生成的,但是它们的缓存特征与静态文件的完全相同。
图 2. 以嵌入 HTML 模板代码形式提供数据库记录的 Web 站点
此类早期应用程序的一个简单例子是统一目录 Web 应用程序。这种应用程序通常以如下方式工作:
这种交互的一个重要特性是它是幂等的(idempotent),也就是说除非底层资源发生变化(例如 Bill 修改了自己的电话号码),否则同一请求的结果总是相同的。这意味着浏览器或代理服务器都可以在本地对 Bill Higgins 的文档进行缓存,只要底层资源没有发生变化,那就可以从本地缓存中检索资源,而不再需要从远程服务器检索。这种方法能提高用户感受到的响应性,并增加系统整体效率和可伸缩性。这些早期的动态 Web 应用程序可以很好地工作,将大量的信息送至用户指尖。
融入式 Web 应用程序
下一代 Web 应用程序的目标就是高度融入,提供个性化的内容和富应用程序模型。在过去十年中,Web 开发人员成功创建了这些融入式应用程序。一个非常恰当的例子是 Amazon.com 电子商务站点。当用户与 Amazon Web 应用程序进行交互时,它会创建复杂的客户页面来推荐有针对性的商品,显示浏览历史记录,并显示用户购物车中商品的价格。
融入式服务器端应用程序和 REST融入式 Web 应用程序确实非常有用,但服务器端的融入式 Web 应用程序风格从根本上来说是不符合 REST 架构准则的。具体来说,它违背了一项关键的 REST 约束,并且没有利用 REST 最为重要的一些优点,因此又产生了一组新问题。
违背了 “无状态服务器” 约束