商品详情

目录
前言 xx
开场:嗯,那是一次有趣的旅行,不是吗 xxviii
Bob、Carol 和BigCo 公司 xxx
第1 章 从HTML 到简单Web API 1
任务处理系统(TPS)Web 应用 4
来自服务器的HTML 5
将通用Web 浏览器作为客户端 9
评价 9
Task 服务Web API 10
Web API 的常规实践 10
设计TPS Web API 11
实现TPS Web API18
评价 24
总结 25
参考资料 26
第2 章 JSON 客户端 29
JSON Web API 客户端 30
Objects 31
Addresses 34
Actions 35
小结 38
JSON 单页面客户端38
HTML 容器 38
顶层解析循环 40
Objects、Addresses 和Actions 41
小结 47
应对变化 47
添加字段和过滤器 48
编写一个新客户端 52
总结 54
参考资料 57
第3 章 表述器模式 59
XML 还是JSON :选一个吧62
新的分支:超媒体格式 63
“唯一正确”的谬误 65
重建(reframe)问题 66
表述器(Representor)模式 68
从功能中分离格式 69
选择算法 69
适配和翻译 71
服务端模型 74
处理HTTP Accept 头部参数 74
实现消息翻译器模式 74
通用表述器模块 76
WeSTL 格式 76
表述器的范例 81
总结 84
参考资料 86
第4 章 HAL 客户端 89
HAL 格式 91
Links 93
Objects 和Properties 94
内嵌Links 和Objects 95
小结 97
HAL 表述器 97
Links 98
Properties 99
内嵌内容 100
HAL 表述器构建TPS 输出示例 102
HAL SPA 客户端 104
HTML 容器 105
顶层解析循环 106
Links 107
内嵌内容 109
Properties 113
为HAL 处理Action 114
小结 116
应对变化 117
添加ACTION 117
HAL-FORMS 扩展 121
规范 121
请求HAL-FORMS 文档 123
实现 124
总结 125
参考资料 128
第5 章 可重用客户端应用的挑战 131
你在解决什么问题 133
设计的双钻石模型 134
闭合方案 vs 开放方案 134
交互建模 136
Maldonado 的机制 137
Verplank 的人类视角 139
超媒体交互循环 141
RPW 循环 141
用代码实现RPW 143
处理Verplank 的KNOW 步骤 144
总结 148
参考资料 150
第6 章 Siren 客户端 153
Siren 格式 155
Entities 157
Class 158
Properties 158
Links 159
Actions 159
SubEntities 160
小结 162
Siren 表述器 162
顶层循环 163
Class 164
Properties 164
Entities 165
Actions 166
Links 168
TPS 通过Siren 表述器输出示例 169
Siren SPA 客户端 172
HTML 容器 173
顶层解析循环 173
Links 174
Entities 176
Properties 178
Actions 181
小结 184
应对变化 184
添加邮箱字段和过滤器 185
测试邮箱字段 187
Profile 对象描述(POD)扩展 190
POD 规范 191
实现 192
在Siren 中使用POD 展示对象 194
小结 195
总结 196
参考资料 198
第7 章 版本化与Web 199
互联网中的版本化 201
TCP/IP 的健壮性原则 202
HTTP 中的MUST IGNORE 203
HTML 的向后兼容性 205
非破坏性变更指南 206
API 设计者 206
服务端实现者 209
客户端实现者 215
总结 223
参考资料 225
第8 章 Collection+JSON 客户端 227
Collection+JSON 格式 229
Links 232
Items 233
Queries 234
Template 235
Error 237
小结 237
xviii | 目录
Collection+JSON 表述器 238
顶层处理循环 238
Links 239
Items 240
Queries 243
Template 244
Error 245
Collection+JSON SPA 客户端 246
HTML 容器 246
顶层解析循环 248
Links 249
Items 250
Queries 253
Template 255
Error 257
小结 258
处理变更 258
在TPS API 中添加Note 对象 259
Cj 和OAA 挑战 265
小结 266
扩展Collection+JSON 266
用Cj-Types 支持改善的输入 267
Cj-Suggest 扩展 271
小结 275
总结 275
参考资料 279
第9 章 超媒体与微服务 281
UNIX 哲学 284
BigCo 的TPS 微服务 285
Task 服务与Collection + JSON 286
User 服务与Siren 290
Note 服务与HAL 293
一个客户端,统领全局 296
Home 服务 297
多格式客户端SPA 容器 298
可以切换格式的客户端UI 301
总结 308
参考资料 312
结语:拥抱你的未来 313
附录A 项目清单 315
附录B 工具与资源 319
前言/序言
推荐序:一场与超媒体的未了情缘
在2007 年,当我初次翻译Roy Fielding 关于REST 的博士论文(中文名为《架构风格与基于网络应用软件的架构设计》)时,自己对Web 的整体架构是毫无概念的。无知者无畏,当时我仅仅是出于求知欲就开始了翻译工作。后来我发现这个挑战严重超出了我的能力范围,Fielding 的博士论文是我翻译过的专业技术著作中难度最高的。后来我在2013 年重新翻译了这篇博士论文,力求把初次翻译时的大量问题和留下的遗憾都弥补上,而不至于误人子弟。
这篇博士论文是一座内涵丰富的宝藏,可以说是2000 年前Web 架构相关论文中的集大成者,其重要性不亚于Tim Berners-Lee 爵士的论文。文中系统地阐述了HTTP 1.1 协议背后的设计原理——REST。绝大多数不理解REST 思想的Web 开发者都会陷入两个误区之中:一个是将HTTP 简单看作是一种传输协议(而不是应用协议),另一个是完全忽视超媒体的重要性。在2005 年REST 思想随着Web 2.0 的兴起和迅速发展而逐渐普及之后,脱离第一个误区的Web 开发者越来越多,但是能脱离第二个误区的Web 开发者还是极少数。Fielding 博士其实从最初就认为REST 和超媒体是不可分割的,而HTTP 1.1 最重要的设计目标就是更好地支持超媒体。在当时的语境中,这个超媒体自然就是HTML。因为关于超媒体的误解如此之多,所以Fielding 博士在2008 年写了一篇博客文章RESTAPIs Must be Hypertext-driven(《REST API 必须是超文本驱动的》)。
这篇博客引起了Web 开发社区的广泛讨论和反思,随后RESTful Web Services 一书的作者Leonard Richardson 提出了一个Richardson 成熟度模型。这个模型将RESTful API 划分成了3 个等级,把能够熟练应用超媒体的RESTful API 列为了最高等级——第3 级。然而很多年过去了,在普通Web 开发者看来,这似乎仍然是一个乌托邦式的目标。有些RPC 铁杆粉丝总是会拿这个来讥讽REST 爱好者,把他们说成是中看不中用的API 设计美学爱好者。这些传统的观点过于强大,以至于REST 爱好者对于在API 设计中使用超媒体也视为畏途。
当然,我们都是工程派,而不是学院派,随便给别人乱扣学院派的大帽子是一种不尊重人的行为,也是不求甚解的体现。包括REST 思想的创造者Roy Fielding 也是“如假包换”的工程派。他早年为很多开源项目贡献过大量代码,还指导了大量HTTP 客户端/ 服务器端开发团队,他的实战能力肯定在绝大多数开发者之上。REST 当然并不是一种API设计美学,它更像是中庸之道,包含了设计Web 应用的各种架构权衡。虽然Fielding 在设计HTTP 1.1 和撰写博士论文时,超媒体主要指的是HTML,但是REST 是通用的理论,能支持的超媒体类别远不止HTML 一种。在Fielding 发表2008 年博客文章之后,Web开发社区与超媒体相关的研究和开发实战非常活跃,出现了大量新型的超媒体,而且越
新出现的超媒体,越是基于JSON 而非XML 的。一直很支持REST 设计开发的O’Reilly出版社,也不失时机地出版了很多REST 开发相关的图书,这些图书目前已经形成了一个强大的系列,包括:
y RESTful Web Services
y RESTful Web Services Cookboo(k 中文版为《RESTful Web Services Cookbook中文版》)
y REST in Practice(中文版为《REST 实战》)
y RESTful Web APIs(中文版为《RESTful Web APIs 中文版》)
y RESTful Web Clients(中文版为《RESTful Web Clients:基于超媒体的可复用客户端 》,即
本书)
另外还有很多针对某个开发平台的REST 开发图书,例如:
y RESTful .NET
y Building Hypermedia APIs with HTML5 and Node(中文版为《使用 HTML5 和 Node
构建超媒体API》)
y PHP Web Services: APIs for the Modern Web
在这些优秀的REST 开发图书之中,涉及了超媒体的图书中最有代表性的是如下3 本:
y REST in Practice(中文版为《REST 实战》)
y RESTful Web APIs(中文版为《RESTful Web APIs 中文版》)
y RESTful Web Clients(中文版为《RESTful Web Clients:基于超媒体的可复用客户端 》,
即本书)
我有幸作为REST in Practice 一书的翻译负责人,赵震一负责翻译RESTful Web APIs,曾著负责翻译RESTful Web Clients。我们就像是一个接力赛的团队一样,在7 年的时间里,把接力棒传递下去,希望能通过这3 本书向国内的Web 开发者全面展示RESTful API 和超媒体的独特魅力。
这3 本书由浅入深,逐步揭开了支持超媒体的第3 级RESTful API(也就是所谓的Web API)的神秘面纱。尤其是第3 本书RESTful Web Clients,令人信服地展示了使用超媒体之后,对于API 客户端代码的复用性和松耦合起到的巨大作用。除此之外,这本书最重要的贡献是让超媒体变得如此平易近人,要达到这个目标其实是非常困难的。作者Mike Amundsen 虽然功力深厚,但为了保证本书的质量,原著足足推迟了一年时间才上市。结果不负众望,Mike 为读者奉献了一本高质量的图书。连Roy Fielding 在Twitter 上也承认Mike Amundsen 对于超媒体如何使用的理解,与REST 博士论文是最接近的。相信认真阅读完本书的Web 开发者对在API 设计中适当使用超媒体不再会那么犹豫。其实在API 设计中适当使用超媒体,就应该像我们平时写代码时要写单元测试一样习以为常,并且熟能生巧,不断探索在API 设计中使用超媒体的乐趣。
另外我还建议读者在读完RESTful Web Clients 之后,再去认真读一下Mike Amundsen 的上一本书RESTful Web APIs,因为这两本书有很强的关联性。RESTful Web APIs 虽然很棒,但是偏重于概念阐述,实战性不足,RESTful Web Clients 弥补了RESTful Web APIs 在实战性方面的缺憾。思想的发展是有传承性的,没有几年前的RESTful Web APIs 就不会有RESTful Web Clients。对于API 来说,服务器端是皮,客户端是毛,皮之不存,毛将焉附?
顺便说一下,虽然现在HTTP 1.1 已经升级到了HTTP 2,不过REST 和超媒体的思想是完全适用的。如果熟悉HTTP 2,你会发现,其实HTTP 2 的设计还是为了更好地支持超媒体(特别是HTML5),HTTP 2 仍然是与超媒体紧密相关的。这再次证实了Fielding在REST 博士论文中所阐述的思想,REST 是Web 自身的架构风格,REST 就是一切优秀Web 应用的灵魂,而REST 自身的灵魂就是超媒体。超媒体是计算机软件领域最伟大的思想之一,它是Web 应用取之不竭的力量源泉。
开卷有益,最后我代表国内的Web 开发者感谢本书的两位译者曾著、徐必涛的辛勤工作。
也感谢博文视点张春雨老师,他10 年来坚持不懈地支持REST 开发图书的出版。
Web 架构师 李锟
2018 年3 月4 日于上海
译者序
2017 年年末,就职小米的一位前同事送了我一枚F 码,我用它抢购到一枚小爱音箱。我满怀期待地装上“小爱同学”,希望能够通过她用语音控制所有小米产品。但我失望地发现,早先我购买的YeeLight 床头灯并不能接受“小爱同学”的指挥——YeeLight 床头灯的客户端只能适配其出厂时的服务端所提供的功能,在服务端扩展新的功能,比如接入智能语音控制之后,已经发布的客户端却无法跟上,无法获得新功能。
随着互联网尤其是物联网的发展,跨企业、跨行业的互联需求越来越多,上述遗憾会频繁发生,无疑会造成巨大的浪费,也阻碍了物联网的发展。我们迫切需要服务端和客户端相互独立演化的能力,这正是RESTful 服务端与客户端的用武之地,也是本书的主要目的。
本质上,服务端和客户端独立演化的能力取决于双方的实现细节的解耦程度。首先,如果服务端与客户端紧密耦合,服务端变更就很可能造成客户端失效。例如,服务端和客户端通过RPC 的IDL 来约定服务接口,那么当服务端的变更引起过程名、参数或返回值的变更时,客户端就很难不受其影响。又例如,服务端的Web Service 遵循一套URL template 规约,客户端根据服务端提供的规约文档编码,如果服务端改变了资源名称或资源之间的关联关系,也会导致客户端失效。其次,与服务端紧密耦合的客户端显然也无法正常接纳服务端推出的新功能。
REST 解决的思路就是将可能变化的部分抽象出来,融入服务端响应的消息体中,如果客户端拥有解读这些变化的能力,也就使双方都获得了独立演化的能力。
在过去我们非常熟悉的“通用浏览器+ 服务端渲染逻辑(CGI、JSP、ASP、PHP 等)+HTML”方案中,服务端输出了整个HTML 文档,自然也包含了服务端所有可能变化的部分。从理论上说,客户端和服务端的确获得了相互独立演化的能力——浏览器是通用的,不需要应用程序员编写任何客户端代码,也并不因为服务端改变了JSP 脚本或增加一个功能,就需要升级浏览器。这是一个极为流行的方案,成功地挤掉了C/S 结构的份额,成为当时互联网应用的主流方案。
然而,这个服务器渲染的方案并不够好。因为服务端响应是完整的HTML 文档,不仅有业务数据而且包括渲染的每一个细节,客户端要么全要,要么全不要。如果客户端希望对业务数据再加工,或者局部渲染,就不得不剥离易变的其他元素,例如
这个渲染相关的元素。写过爬虫的程序员应该深有体会,好不容易把有用数据从HTML 大杂烩里提取出来,结果目标网站稍微改动一些风格布局,原先的爬虫程序就失效了。由于难以局部渲染,人们不得不忍受HTML 页面跳转的糟糕体验。AJAX 和JS 客户端渲染脚本的兴起成为压倒骆驼的最后一根稻草,传统的服务器渲染方案被逐步取代了。
拥有JS 渲染脚本和静态HTML 模板的富客户端,将服务端渲染方案中view 的职责从服务端抢了过来,服务端只输出数据,不必带上各种HTML 标签。职责的分离大大促进了复用,一个服务端可以拥有多个不同展现形式的客户端,一个客户端可以mashup(mashup的定义请参考https://en.wikipedia.org/wiki/Mashup_(web_application_hybrid) )多个服务端,跨企业的应用互联变得很流行。但这样一来,过去C/S 结构的老问题——服务端与客户端紧耦合的毛病又出现了,如果客户端团队与服务端团队不是同一拨人,独立演化造成不兼容就会成为大问题。
客户端渲染和客户端服务端独立演化能否兼得?本书给出了答案。
随着格局的转变,组织需要再次考虑方程两边的平衡问题。从广义上讲,我认为这会产生更好的API,但它们不会都是“玫瑰”。正如我之前所提到的,你可以买到无数的书籍来帮助你了解方程的服务端一边,但是在客户端方面却完全没有一个类似的指导手册——至今仍是如此。
自从Mike 告诉我他开始着手这一工作以来,我一直在期待着这本书,而他也确实没有
让我失望。对于Web API 方程式中缺失的那部分,本书堪称一部梦幻般的指南,我相信
它的作用和影响在未来数年内将得到关注。希望你也可以像我一样享受这本书的阅读过
程。
——Steve Klabnik
前言
“始阶段是工作中最重要的部分。”
——柏拉图(Plato)
基于Web 的REST 和超媒体服务正日趋普遍,但却鲜有客户端可以利用这些API 的强大功能。这主要是因为缺乏创建成功的超媒体客户端的技术和模式——长期以来它们一直被忽视。然而,如果可以采取恰当的方式,基于超媒体的客户端应用将会比典型的一次性客户端具有更强的稳定性和灵活性。
本书旨在为读者提供一个坚实的背景知识和一些可工作的示例源码,这些示例为如何处理超媒体API 提供了明确的建议。本书的主要思想之一是客户端应用程序应该依赖于Request、Parse 和Wait 所构成的循环,我简称其为RPW 循环。这是所有电脑游戏采用的实现方式,也是所有事件驱动接口从窗口式工作站(windowing-style workstation)到响应式机器接口(reactive machine interface)的工作方式。
有人告诉我,一些前端的开发人员可能会认为RPW 模式比较生僻,甚至也有人认为我的建议比较“激进”。对于这些观点,我都能理解。当下,众多的前端开发库和实践都在致力于设计用于专门构建的一次性用户界面,这些界面难以修改,并且很难在运行时对服务提供的新信息做出反应。不过,在阅读本书的例子后,我希望前端开发人员(他们中的大多数都比我的经验更丰富)能够在目前初步工作的基础上创造出更丰富的最佳实践、工具和可重用的库,为越来越多的超媒体API 打造高质量的用户体验,力争在不需要频繁升级的情况下满足高质量的用户体验需求,以及不断发展的服务接口自适应客户端的需求。
本书讲了什么
本书将带领读者开启一段从个性化定制实现到强大的通用客户端应用的旅程,同时向你展示如何利用那些支撑万维网良好运行的基本原则。本书包括以代码为中心的章节信息和对相关重要主题的探索,比如表述器模式、人机交互模型和Web API 在版本控制上的挑战等。当然,其中也少不了大量的代码(我为本书创建了20 多个GitHub 仓库),包括一些小的代码片段。不过,这些片段单独看可能不易理解。因此,我会为读者指出完整的在线代码库的位置,你可以在相关代码库中找到本书所涵盖的全部功能实例。
各章内容
本书探讨了通用超媒体风格客户端的世界,包括它们的外观、与典型JSON 对象客户端的区别,以及客户端和服务端开发者如何构建更易于支持和适应的系统。本书包含了一些专项讨论所选格式(如HTML、纯JSON、HAL、Siren 和Collection+JSON)的章节,以及所有Web 开发人员需要熟悉的理论和实践的章节,包括服务端对消息格式的支持、人机交互模型、版本控制,以及一个在同时与多个独立的后端服务进行交互时可以支持多种超媒体格式的解决方案。
本书的大多数章节都可以独立成章,在阅读时可以不讲究先后顺序。不过,为了更充分地理解和吸收本书的内容,我鼓励你将本书看成一次单程旅行,按照顺序从头读到尾。这里简单介绍一下本次旅程的路径。
第1 章,从HTML 到简单Web API
本章向我们介绍了一个经典的纯HTML 客户端。我们将通过它来了解浏览器的基本工作原理,以及它们是如何影响人们看待Web 中那些超媒体格式的。此外,本章还介绍了将纯HTML 服务转换为一个原始的纯JSON 服务的过程。该服务将是我们为本书构建的所有其他客户端应用程序的基础。
第2 章,JSON 客户端
大多数的客户端Web 开发人员都会构建JSON 客户端,它会记住所有的URL,处理静态对象,并通过固定的工作路径来导航。构建JSON 客户端是一个很好的开始,不过时间却证明它是一个糟糕的工作方式。在本章中,我们将讨论如何克服在维护纯JSON 风格客户端应用程序时的挑战。
第3 章,表述器模式
表述器模式是处理服务器输出的一种简单而重要的方式,也是将内部对象模型转换为外部消息模型的过程。我们将在本章中审视该模式(及其源头),并介绍如何使用服务器上的Web 服务迁移语言(WeSTL)和浏览器客户端上的HTML DOM 将该模式应用于API 提供方。
第4 章,HAL 客户端
HAL 媒体类型是目前较为流行的超媒体格式之一。比如在Amazon 的Web 服务团队中,至少有两个API 使用了HAL。对于所有Web 客户端都需要处理的三个重要元素,HAL 负责处理其中之一: ADDRESS 挑战。我们将看到如何将HAL 作为消息格式来构建一个通用客户端,以及如何通过HAL-FORMS 扩展来提高HAL 的处理能力。
第5 章,可重用客户端应用的挑战
你会注意到,我们所构建的多数客户端看起来都很类似。从本质上讲,我们正在建立能够在探索周围世界(以某种有限的方式)的过程中发展自己的“探险者”。这些客户端都采用了Request—Parse—Wait 循环,即RPW 模式。该模式基于我们如何与世界交互这一命题下的几个经典概念,我们将在本章中探讨它们。
第6 章,Siren 客户端
Siren 内容类型是另一种强大的超媒体类型。Siren 目前被用作Zetta IoT 平台的一部分,旨在处理Web 客户端的三个关键任务中的两个:ADDRESS 和ACTION。我们将看到使用Siren 作为消息格式来构建一个通用客户端,也会通过探索Siren 拓展(Profile for Object Display,即POD)来增强它在UI 上显示元数据的能力。
第7 章,版本化与Web
当你开始将超媒体类型作为客户端Web 应用程序的基础时,API 版本的概念会发生什么变化?本章将讨论管理随时间变化的各种尝试,以及如何依赖基于消息的超媒体风格的API 来减少当接口特性发生变更时也要变更接口契约的问题。
第8 章,Collection+JSON 客户端
在本章中我们将探讨另外一种超媒体格式:Collection+JSON,或称为Cj。Cj 能够处理Web 客户端中的所有元素:OBJECT、ADDRESS 和ACTION。我们将看到如何将Collection+JSON 作为消息格式来构建一个通用客户端,并学习如何扩展Cj 的数据显示和验证程序。
第9 章,超媒体与微服务
创建一个可以无缝调用多个服务的通用超媒体客户端需要什么?如果这些服务使用的超媒体类型各不相同,又需要什么呢?当我们谈论消息格式时,该怎样制作一个可以“说”多种语言的客户端应用?这一切将在最后一章中揭晓。
对话
本书的所有章节都以简短的小插曲或对话开始和结束。我们通过这些虚构的对话来说明,组织在思考如何在互联网上创建可扩展且稳定的项目时所遇到的挑战。这些对话既是各章主题的铺垫,也是主题的总结。
此外,对话也是一种提示,让读者有机会思考所提出的挑战,以及如何应对这些挑战并给出解决方案。每章从对话开始读起,读完后花几分钟时间来描绘(也可以写下来)一下你对于如何解决问题的想法。这种方式可以帮助你对书中提供的解决方案形成更深刻的认识,并对自己的问题解决能力有额外的洞察。
最后,这些对话还可以帮助那些只想跳跃阅读书中部分内容的读者收获一些感悟。你可以单独阅读对话,并收集相关的基础信息。各章内容也正是对对话中的细节和微妙之处进行了深入讨论。你可能会发现,至少在某些章节中,阅读对话可以获取当前主题或挑战相关的所有信息,而且还很不错。
艺术作品
本书包含了一些才华横溢之辈的艺术作品和图表。Dana Amundsen, 路易斯维尔(Louisville) KY 的一位成功的艺术家,和我一起创作了本书中出现的人物Bob 和Carol。此外,她还设计了示例程序中所使用的BigCo 徽标。事实上,Dana 创作的作品比本书所包含的要多得多,希望在不久的将来可以通过其他方式将这些艺术作品分享出去。
- 电子工业出版社有限公司
- 电子工业出版社有限公司有赞官方供货商,为客户提供一流的知识产品及服务。
- 扫描二维码,访问我们的微信店铺