We FALL ASleep At Night, We Do REST Right

Github 同步发表链接

前言

笔者在上一篇文章中提过,任何一种非“强制性”约束同时也没有“标杆”工具支持的开发风格或协议,最后都会在不同的程序员手中得到不同的诠释,微服务是如此,DDD 是如此,笔者把它称为技术思想上的“康威定律”。不出意外的,REST 同样难逃此劫。光是在学习和收集资料的过程中,笔者就已经见过不下十多篇此类理解,甚至于在 url 中使用短划线或下划线连接单词也是众口难调。

尽管这只是小事。

微软也发布过关于如何设计 REST API 的开发指南,但是不幸的是,REST 的创始人 Roy Fielding 认为微软的 REST API 规范与 REST 没有多大关系。

“即使是我最糟糕的 REST 描述也比微软的 API 指南提供的总结或参考要好很多。”

那什么才是正确的 REST 描述呢,或者说,REST 是什么。本文的创作动机便是希冀于解决这样一个问题。

本文假设读者已经具备基本的 REST 和 Web 知识,哪怕你们现在认为 HTTP API 就是 REST API 也可。

REST 起源

REST 英文全称为 Representational State Transfer,又名“表述性状态移交”,是由 Roy Fielding 在《架构风格与基于网络的软件架构设计》一文中提出的一种架构风格(Architectural Style)。而在这篇 REST 圣经问世之前,R.F 博士就已经参与了 HTTP 1.0 协议规范的开发工作(1996年),并且负责了 HTTP 1.1 协议规范的制定(1997年)。

一种架构风格由一组准确命名的,相互协作的架构约束组成。当我们在谈论 REST 本质的时候,我们谈论的其实是架构约束。

REST 用以指导基于网络的分布式超媒体系统的设计和实现,Web(即万维网)就是一种典型的分布式超媒体系统。可以确定的是,在制定 HTTP 协议的过程中,R.F 博士就已经以 REST 架构风格作为指导原则来完成相关工作。论文中提到了以下内容:

“在过去的6年中,我们使用 REST 架构风格来指导现代 Web 架构的设计和开发。这个工作是与我所创作的 HTTP 和 URI 两个互联网规范共同完成的,这两个规范定义了在 Web 上进行交互的所有组件所使用的通用接口。”

“自从1994年起,REST 架构风格就被用来指导现代 Web 架构的设计与开发。”

“开发 REST 的动机是为 Web 的运转方式创建一种架构模型,使之成为 Web 协议标准的指导框架。”

“REST 的第一版开发于1994年10月至1995年8月之间,起初,在我编写 HTTP/1.0 规范和最初的 HTTP/1.1 建议时,将它用来作为表达各种 Web 概念的一种方法……”

Web 架构规范主要包括 HTTP, URI 和 HTML 等。

所以我们也不难理解为什么 REST 与 Web 和 HTTP 能够结合得如此紧密。尽管直到2000年,这只“鸡”才在下完鸡蛋后,出现在了世人面前。

REST 演化

REST 约束

无论是否愿意承认,REST 一开始就是为 Web 而服务的,可以这么说的是,REST 是现代 Web 的架构风格,Web 也是 REST 最典型和最成功的案例。包括在 R.F 博士的论文中,他也是在解决现代 Web 需求(无法控制的可伸缩性和独立部署)的过程中而逐步推导出 REST。前文已经提到一种架构风格是由一组准确命名的,相互协作的架构约束组成。而所谓架构约束,便是这个推导过程中最重要的产物。甚至高于 REST 本身。

早先的 Web 与 REST 所描述的模型有着大量出入,然而正是在对应的 HTTP 和 URI 规范出炉后,才有了所谓“现代 Web”的说法。笔者更愿意把“现代 Web”的定义期限定为1996年后。

客户端 - 服务端

设计与实现上的关注点分离。

无状态

在客户端没有发起请求时,服务器并不知道它的存在。同样的,服务器无须维护当前请求之外的客户端状态,从而改善服务器的可伸缩性。Session 和 Cookie 都是“需要”被抛弃的。
如果有些应用状态重要到服务器需要去关心,那它应该成为一个资源。

缓存

对于客户端而言,使用缓存则是维护状态和提升性能的更好做法。

统一接口

使 REST 架构风格区别于其他基于网络的架构风格的核心特征是,它强调组件之间具有一个统一的接口。实现与他们所提供的服务是解耦的,这促进了独立的可进化性。同时这也引申出了其他的约束:资源识别;通过表述来操作资源;自描述信息;超媒体作为应用状态引擎(即 HATEOAS)。下文会专门说明。

分层系统

“分层系统”约束在“客户 - 服务端”约束的基础上增加了代理组件和网关组件。尽管笔者认为代理和网关都不是重点,“分层系统”约束更注重的是“在客户端和服务端之间添加一个组件应该是一个透明操作”,组件只能“看到”与其交互的相邻层(是不是想到了[迪米特法则][5]),使用层级来封装服务,同时能够支持负载均衡和诸如安全性检查的功能。

按需代码

这是六大约束中唯一的可选约束。REST 允许客户端通过下载并执行脚本或其他形式的代码,对客户端的功能进行扩展,从而提高客户端的灵活性和性能。通俗点说,HTML 中的 `
posted @ 2018-06-19 10:23  白细胞  阅读(780)  评论(3编辑  收藏  举报