问题:如果一个接口被认为不是RESTful(根据Fielding),当客户端无法利用时,可以将REST中的HATEOAS视为有效命题吗?来自Response Hypertext(超媒体)的带内数据(URI' s),无需引用外部(带外)文档,因此根据Fielding紧密耦合Client和Server,我们怎么做除了罗伊菲尔丁的表面证据不足assertion?
在我看来,菲尔丁的论述使得HATEOAS和REST成为一种内部矛盾的命题,这种命题无法用当前的技术来实现 - 除非有人知道怎么做而不引用带外数据?
(编辑)我怀疑没有人正在阅读/已阅读菲尔丁的咆哮,所以这里是最相关部分:
" 应输入REST API,除了初始URI(书签)和适用于目标受众的标准化媒体类型集之外没有任何先验知识(即,任何客户都应该理解可能使用API)。从那时起,所有应用程序状态转换必须由客户端选择服务器提供的选择来驱动,这些选择存在于接收的表示中或者由用户对这些表示的操纵所暗示。转换可以由客户端对媒体类型和资源通信机制的知识来确定(或限制),这两者都可以在运行中(例如,按需代码)进行改进。 [这里的失败意味着带外信息正在推动互动而不是超文本。] "
我们都断言我们必须拥有URI初始数据流之外的可用方法的带外知识。请注意菲尔丁如何非常强烈地告诉我们这是失败的。然而,包括我在内的我们是如何做到这一切的。但菲尔丁尖叫着 No 回到我们身边。
(编辑:因为没人读它的解释)。
答案 0 :(得分:0)
所以,我的问题的答案似乎是 none 我们知道如何按照Fielding所说的方式完成它,所以没有人知道如何实现HATEOAS兼容的RESTful API违反Fielding关于带外数据的主要断言,因此使我们的应用程序非RESTful。
每个人都强烈认为他们有正确的答案,但我们都忽略了罗伊菲尔丁说我们都错了的事实。他说我们都在写RPC。
Roy Fielding: REST APIs must be hypertext-driven "我对使用任何基于HTTP的界面调用REST API"
的人数感到沮丧归结为这样一个事实,即我们并没有构建那种适合罗伊关于REST的论文的应用程序。实际上,他认为我们将我们的URI作为CDATA的一部分,包括"方法"或者URI的上下文无疑会提供它,就像FORM元素那样。他明确指责OpenSocialst REST API声明它不 RESTful。
这里:“具有href属性的锚元素创建一个超文本链接,选中后,在与CDATA编码的href属性对应的URI上调用检索请求(GET)。”标识符,方法和媒体类型是正交关注点 - 方法没有给出媒体类型的含义。相反,媒体类型告诉客户端使用什么方法(例如,锚意味着GET)或如何确定要使用的方法(例如,表单元素表示查看方法属性)。客户端应该已经知道方法的含义(它们是通用的)以及如何取消引用URI。
我倾向于设计提供此方法的JSON响应:
GET /account/12345 HTTP/1.1
{
"account": {
"number": "12345",
"currency": "usd",
"balance": "100.00",
"deposit": {
"href": "/account/12345/deposit",
"action": "POST"
},
"withdraw": {
"href": "/account/12345/withdraw",
"action": "POST"
},
"transfer": {
"href": "/account/12345/transfer",
"action": "POST"
},
"close": {
"href": "/account/12345/close",
"action": "DELETE"
}
}
}
...根据需要为设计添加其他属性,但这些是基础知识。
我相信这允许客户端被编写为RESTful,但这样做我正在使用响应主体,Fielding说这不是他想要的。
答案 1 :(得分:0)
REST允许的三个先验知识:API的主页(在浏览器中,这是由用户键入地址栏提供的);了解常见的媒体类型,例如HTML(由浏览器开发人员提供);通知客户端应用程序的链接关系可以在决定做什么时查看(例如,rel=stylesheet
链接会被图形浏览器自动下载和解析,以使它们呈现的文档看起来很漂亮。
REST禁止的是,客户知道它可以执行诸如从您网页上的某个位置读取ID然后将其附加到youtube.com/watch?v=
的末尾以获取YouTube视频。相反,您应该定义“视频剪辑”链接关系,并使用媒体类型的超链接机制来提供完整的URL,而不仅仅是ID。
答案 2 :(得分:0)
不,REST和HATEOAS互不矛盾。事实上,这个命题甚至没有意义,因为HATEOAS是REST定义的一部分。它们不是两件事。
为了更好地理解菲尔丁的带外知识,我建议考虑使用网络浏览器。 Web浏览器是实现一组标准(HTTP,HTML,URI等)的通用客户端。客户端实现的任何标准都可以被认为是带内的。任何未在通用客户端实现的标准中表达的内容都是带外的。
如果您的资源看起来像这样
GET /some/resource HTTP/1.1
Content-Type: application/json
{
"author": "/authors/me",
"foo": 42
}
作为一个人,我可以看一下这一点,并认识到“作者”的价值看起来像一个链接,我可以尝试遵循它,但通用浏览器只能将其识别为普通的JSON。这只是一个字符串。解释“作者”是一个链接需要带外知识。
解决方案是选择定义如何表达链接的超媒体媒体类型。这是用HAL表示的那个例子。
GET /some/resource HTTP/1.1
Content-Type: application/hal+json
{
"_links": {
"author": { "href": "/authors/me" }
},
"foo": 42
}
可以开发理解HAL的通用客户端。我的API和您的API都可以使用相同的客户端,而无需了解彼此或客户端了解任何API。
关于如何知道链接使用哪种方法的问题也取决于要定义的超媒体媒体类型。 HTML通过定义语义暗示方法的结构来实现。锚标记<a href="/foo">foo</a>
表示GET请求。表单标记具有类似的明确定义的语义。基于JSON的超媒体格式必须为这些结构定义自己的结构和语义。所有这些都被认为是带内的,因为它是可以由通用浏览器实现的标准的一部分。
因此,如果您希望获得Roy API对您的REST API的批准,您需要使用标准化的通用超媒体媒体类型,该类型能够描述您的应用程序需要执行的所有操作。我最喜欢的是JSON Hyper-Schema。它是最好的描述类似没有带外知识的表单帖子,因为它使用JSON Schema来描述服务器期望的数据。