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