首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

揭开 RESTful 的神秘面纱:误解与真相

‍‍

作者 | tef        译者 | 明明如月

责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

事实真相如下:

对 RESTful API 的误解

REST 是过去 Web 的工作方式

识别 非 Rest 架构

一个真正的 Restful API:网页抓取

对 RESTful API 的误解

那些声称 “这是一个 Restful API” 的人,大多数时候可能只是在夸大其词,完全是误导。那些宣称“你的产品应该是 Restful”的人,通常他们的意思是“请按照我喜欢的方式来做事”。这个“我喜欢的方式”通常是“正确地使用 HTTP”,再加入一些其他元素。 这些“其他元素”通常是一些奇特的迷信和命名规范,而在真正的 Rest 架构中,这些并不重要。

换言之,真正的 Rest 并不仅仅是关于 CRUD 操作或是暴露一个文件系统,也并非关于 URL 的命名方案,或是选择 PATCH 还是 POST。 实际的 REST 是关于“网络浏览器是如何运作的”,并且其核心思想源自一篇完全不同的论文——《通过约束来定义架构风格(defining architectural styles through constraints)》。尽管这篇论文并未对理解 Rest 的工作方式提供直接定义,但其阅读价值仍然不言而喻。

REST 是过去 Web 的工作方式

1、REST 关注的是网页浏览器与网页服务器之间的交互用以构建一个分布式超媒体系统。

2、REST 并非只是关于 APIs,更是关于如何将传输协议(如 HTTP)、接口描述(如 HTML)以及应用状态(如 URL)有机融合。

它展示了如何利用像 HTTP 这样的协议,让你能够隐形地使用负载均衡器、缓存或代理。

它揭示了如何利用像 HTML 这样的接口描述,使服务在网络上以平台中立的方式呈现接口。

它关注于如何在 URL 中存储应用状态,通过链接和表单等方式操作 URL,而不是在客户端或服务器端维护状态。

它阐述了服务器如何改变所有的 URL,只要链接得到了更新,一切仍然能够正常运作。

它举例了 REST 的特性:在两个新标签页中打开"next",你将看到两次相同的页面,而非分别出现第2页和第3页。

它意味着在网页上点击next来进入下一页,而不是要求用户输入/collection?offset=80。

3、REST 也描述了如何使用标准方法来实现这个功能,这样任何网页浏览器都可以访问并与任何网页服务器进行交互。

4、换言之,REST 就是让你能够用自己的网页浏览器与网络邮箱互动的一种方式,而浏览器并不需要了解任何有关电子邮件的信息。

5、最接近 REST 的实际概念是 "理查德森成熟度模型",它将 "成为 REST" 的过程分解为三个简单的步骤:

和负载均衡器和谐共处:不同的事物具有不同的 URL。

与缓存和谐共处:GET 请求可以被缓存,POST 请求则不能被缓存。

与浏览器和谐共处:真正提供 HTML。如今,画出那只该死的猫头鹰。

6、如果没有浏览器,就没有 REST。但是,仅仅有一个浏览器本身并不能让事物符合 REST 原则。

识别非 REST 架构

1、为了充分理解网络的运作原理,我们需要研究那些不完全符合网络规范的案例。

2、以 Gopher 协议为例,相较于 HTTP 来说,Gopher 提供的功能存在局限性:

它基于请求/响应协议

中间件无法真正缓存结果,除非硬编码了某些例外

它具有固定的内置类型列表,而非动态的内容类型字段

仅有菜单类型和目录类型可以链接到其他文件

存在一个特别的命令:搜索操作。任何其他特别的命令都必须通过协议扩展来实现

尽管它是一种浏览器,但并不符合 REST 原则

如果网络按照这种方式运作,为任何 Gopher 客户端编写电子邮件服务将会变得极其困难

3、REST 并不等同于“文件系统”,以 9P 协议为例:

9P 是一种远程文件系统协议,但它使用文件描述符而非传递文件名

客户端进行身份验证,并打开指定路径作为会话的根目录

客户端可以对目录的文件描述符进行 walk 操作以获取文件列表

在协议的意义上,只有目录可以链接到其他文件

文件没有类型化,全部都只是数据块(blob)

4、即使 9P 可以浏览文件系统,也不能像网络那样:

它没有特殊的命令:所有事情都必须通过文件操作来实现,例如,将 "now" 回显到 /service/next_reboot

缺乏超媒体,但有一些相似的习惯用法。一个 Plan9 服务会暴露一些文件,其中有一个文件名,如 /net/mux 返回 1,因此客户端决定从 /net/1/ctl 读取

虽然任何 9P 客户端都可以连接到任何 9P 服务,但一个服务提供的其他功能与另一个服务之间可能存在很大差异

你可以在文件系统上提供电子邮件服务,但最终还是需要在其上编写一个电子邮件客户端,这几乎等同于一个浏览器插件。

值得注意的是,对于 Plan9 的 9P,编写中间件(如代理、缓存或负载均衡器)并不简单,因为必须跟踪文件描述符如何匹配文件

然而,即使使其更像 HTTP 也不够

5、网络不仅仅是“通过 HTTP 提供的文件系统服务”

确实,你可以获得缓存、负载均衡器和代理,但这只是开始

一个大问题是:超媒体在哪里,应用状态的引擎是什么?

使用 WebDAV 服务时,客户端必须知道具体的 URL 地址,而在网络上,通常是通过链接名称访问资源,而不是直接使用 URL 地址访问

任何特殊操作仍然需要通过读取或写入文件的形式实现,每个基于它构建的应用程序可能会有不太相同的功能

相比之下,一个网络会话可以在 URL 内从一个请求携带状态到下一个,因为客户端通过名称导航

6、通常来说,通过 HTTP 的 JSON-RPC 并不完全符合 REST 原则:

使用 HTTP 可以轻松获得缓存、负载均衡和代理,你的 API 并不需要像文件系统那样才能从中间件中受益,但关于 REST 的部分就这些了

有时有一些状态传递,就像 Plan9 返回文件名那样

如果你有一个分页 API,它涉及将一个令牌从一个回复传到下一个请求,那么你就很接近使用 URL 来建模应用状态

问题是什么?他们使用的是模式,而不是 HTML,这个模式必须提前下载

客户端不能像从 HTML 中读取一样从模式中读取

如果一个网页浏览器以同样的方式工作,你将为每个网站下载电子应用程序

7、对于以上的内容,我们总结如下:

REST 是关于如何将 HTML、HTTP 和 URL 结合起来形成一个分布式超媒体系统

它描述的系统可以在不需要新的客户端代码的情况下进行请求的缓存、代理或负载均衡。

它涉及的系统会将应用状态编码在 URL 中

它涉及的系统可以通过点击链接或表单来更改应用状态

经过以上的分析,你可能会问,为什么有人会想制作一个 RESTful API?你甚至可能会问,一个真正的 RESTful API 究竟是什么?答案是,RESTful API 确实存在,它们看起来就像一个网页浏览器

深入理解真正的 RESTful API:从屏幕抓取说起

下面的代码展示了一个真正的 RESTful 客户端应该实现的方式:

是的,这是一个屏幕抓取的例子。真正的 RESTful API 可以被看做一种屏幕抓取:

它使用 HTTP,因此满足了缓存、负载均衡器、代理的需求。

在理论上,API 可以支持 JavaScript, 所以按需加载代码并不是必须的。

并且,因为链接和表单都在 HTML 中,任何的改变都会自动生效。

我知道这听起来疯狂,但这正是 Roy Fielding 教授想要的结果。

对于那些“构建应用程序的应用程序”,他希望它们的工作方式能够像一个 Web 浏览器一样。

如果你的 API 和这个定义不相符,那么就很可能不是 RESTful。

理论上,它可以使用除 HTML 以外的其他语言,但是替代 HTML 的语言必须足够通用,以描述不同类型的接口。有时候,人们声称他们已经建立了一个 RESTful 系统,但是每个接口都是独特的资源类型,而不是使用统一的语言(如 HTML)来描述每个接口。

在真正的 RESTful 架构中,你可以使用同一个客户端来访问多个不同的服务,而且可以在不需要明确要求客户端的情况下将状态从一个请求传递到另一个请求。

也许最吸引人的一点是,通过使用 HTML,REST 可以以一种与现有中间件和服务进行互操作的方式表示比 HTTP 更丰富的操作集,而客户端不需要事先了解和预先知道每个接口的具体信息。‍‍

你是否也曾对某个概念产生过误解,是否也曾在某一刻恍然大悟?

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OB_SuL-gF9T1tmFWtpXeDidw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券