目录
介绍
在我之前的文章中(请先阅读),我试着描述我如何理解REST架构风格,而不管任何通信协议。在这里,我将尝试将此概念映射到HTTP 1.1协议(尽管它也适用于HTTP / 2),以显示bare HTTP不适合完全托管RESTful通信。为了说明我的思维方式,我将使用前一篇文章中的扩展音乐播放器示例。我会将每首歌曲与播放列表名称的数量关联起来,以便进行大容量表示。
REST的核心映射
在寻找泛化的过程中,我将REST的核心定义为一组概念,这些概念包括:转移、状态、表示、安全性和幂等性。
使用表示将状态转移到HTTP很容易。由于HTTP需要请求——响应通信模型,因此引入了描述命令的动词,以区分要求数据的请求提供数据的请求。这些动词是GET和PUT(或POST)。这已经在图片中引入了某种RPC,但还没有破坏REST。HTTP可以携带任何数据,因此应用程序可以*构建其表示。图1显示了使用具有文本表示的HTTP的音乐播放器示例。
图1.使用HTTP的音乐播放器状态转移。
根据HTTP标准,GET应该是安全操作并且PUT应该是幂等的。说明REST的核心可以映射到HTTP。
映射状态修补
为了使用状态修补技术,这是一种不可避免的优化,在实际的应用程序中,状态往往是巨大的,需要有一种可能性来唯一地识别状态块。HTTP使用URI来调用可寻址状态块“资源”。图2显示了读取和写入状态块的示例。
图2.使用URI读取/写入状态块(资源)。
以事务方式传输多个块时发生此问题。
事物读
为了过渡地读取多个状态块(资源),所有这些都需要由客户端在一个自包含消息中请求,然后由服务器在另一个自包含消息中发送。只有当我们可以构造一个包含所有请求资源的URL(例如,寻址资源组)时,这才有可能,因为HTTP本身不支持单个GET请求中的多个URI(参见图3)。类似的情况适用于响应消息,因为无法在单个HTTP响应消息中将多个资源及其URI一起发送回客户端。可以使用POST请求与一些与任何资源都不相关的人工URI一起使用,并将一个负载携带一个请求的URI列表。也可以使用包含所有请求资源的列表的表示以及它们的URI来伪造响应,但是这种解决方案构成了新的“内部协议”,其仅使用HTTP作为沿途的分层隔离的传输机制。
图3.bare HTTP不支持读/写多个资源。
事物写
与事务读相同,bare HTTP不支持多个不相关的状态块的事务性写入。PUT或POST请求既不支持单个HTTP请求消息中的多个URI和表示,也不支持单个HTTP响应消息中的多个状态代码。确实,POST支持多部分有效载荷,但所有这些部分都被寻址到单个URI,因此它只是一个部分的,不是一个令人满意的解决方案(但是,通过使用非标准头扩展HTTP,可以将多部分消息的每个部分与UIR关联起来)。
修补变量状态
在之前的文章中,我描述了如何通过引入表示状态块“时间轴”的元数据来实现RESTful对变量状态的修补。这只能部分映射到HTTP。NEW和MODIFIED形容词可以(语义错误地)映射到PUT动词中,无论目标资源是否存在,动词的行为都不同。MISSING形容词可以被映射到一个DELETE动词。服务器应该对PUT和DELETE进行幂等性运算。问题在于,HTTP不支持修补多个不相关资源的变量状态,其中一些是NEW、一些是MODIFIED,一些是丢失的,因为在单个消息中只允许使用一个动词(参见图4)
图4. HTTP不支持修补变量状态。
结论
HTTP是一个很好的协议,很好地服务于它的目的。它产生了REST并受其影响,但它不是100%RESTful(它实际上是一个可以构建RESTful行为的RPC)。人们试图通过设计聪明的URI和表示来解决这些缺陷,在此过程中打破分层隔离,但最终,bare 100%标准HTTP无法提供真正的RESTful通信,除非每次都传输“整个”状态。
附录:真正的RESTful协议应该是什么样子
涵盖所有示例用例的真正RESTful协议可以使用它认为合适的任何传输,但应按如下方式定义消息:
- 消息类型:枚举(REQUEST,DATA,ACKNOWLEDGEMENT)——辨别消息类型(不是每一个消息类型都需要使用)
- 对于REQUEST类型:
- 唯一块标识符的列表:可以有“整个状态”的特殊标识符,如“/”或NULL;URI是一个很好的候选者,但不是唯一的候选者
- 对于DATA类型:
- 状态块列表:
- 对于每个块:
- 块标识符;
- 块“时效性”标签:枚举(NEW,MODIFIED,MISSING,CURRENT);
- 块表示:任何数据格式;
- 对于每个块:
- 状态块列表:
- 对于ACKNOWLEDGEMENT类型:
- 成功/错误代码。
图5显示了提议的协议的示例消息交换。
图5. RESTful协议示例。
原文地址:https://www.codeproject.com/Articles/1214537/Bare-HTTP-is-Not-Fully-RESTful