在一个现在很有名的blog post中,REST架构的发明者Roy Fielding批评滥用RESTful这个术语 . 特别是,他区分了RPC和REST接口 .
我对此的理解是,在RPC接口中,所有状态转换方法(包括它们的位置和含义)都是客户端先验已知的,而在REST接口中,客户端和服务器只需要说一种通用语言(具有具有先验语法和语义的共享媒体类型,描述状态转换方法的应用程序状态和(位置和含义),以及客户端在运行时发现实际可用的方法 .
我可以看到,当客户端 - 服务器情况是专门的,例如智能灯泡与其桥接器连接时,这是一个非平凡的约束,但当客户端 - 服务器关系是Web浏览器和Web服务器的关系时,isn'上述RESTfulness约束是否满足?
这假定服务器可能提供的JavaScript被视为表示的一部分(因此可以例如包含硬编码链接,因为它可以在不破坏RESTful的情况下) . 另一方面,人们也可以认为组合浏览器js是实际的客户端,然后RESTfulness对JS客户端的设计施加了一个非平凡的约束 . 但是这个观点是不是被解释了?
1 回答
这是对JS代码的一个非平凡的约束 . JS应该被视为客户端而不是资源表示 . 确实,这两者都是,但仅从2个不同的角度来看 . 当JS戴着它的“资源代表”帽时,它是惰性的并且什么都不做 . 当它戴着它的“REST客户端”时,它不再是它作为资源表示的一部分而变得重要 .
硬编码链接不是唯一的问题:JS代码连接字符串以使用内部信息构建链接也是一个问题 . 这些违反REST的行为会影响“可修改性”的属性 . 当您认为JS代码和服务器实现通常是作为同一项目的一部分开发时,这似乎不是问题 . URI和客户端URI构建逻辑可以很容易地保持同步,对吧?但是,如果您有多个应用程序与自己的JS客户端共享单个服务器API实现,该怎么办?对URI的任何更改,都会破坏大量客户端 .
JS代码应该与任何其他客户端绑定相同的规则:链接应该来自服务器提供的资源,语义应该来自对媒体类型的共同理解 .
A Concrete Example
假设我们有一个资源/阅读列表/被定义为书籍集合,如下所示:
JS代码显示列表,如果用户点击某个项目,JS会获取相应的“book”资源,以显示更多详细信息:
GET /阅读清单/ IT
这在所谓的“REST”api中是一种非常常见的模式 . 但是这里发生的事情是JS必须包含一个逻辑,表明你通过将它的id附加到集合的URL来检索一本书 . 换句话说,客户端状态由带外信息驱动 . 您可能会争辩说,由于JS代码本身来自服务器作为资源,因此这不是真正的带外信息 . 但JS现在充当客户端,应该进行分析 .
相反,请考虑/ readinglist / resource的这种表示:
现在JS不必知道如何连接URLS . 相反,它必须具有逻辑,表示通过遵循集合表示中的“链接”URL来获取书籍资源 . 这或多或少复杂吗?它大致相同 . 关键的区别在于,通过这种方法,客户端的状态由超媒体驱动,基于媒体类型的约定语义 . 一旦媒体类型及其处理规则被弄清楚并标准化,它就可以在多个API中重复使用 .