您的问题在 Stackoverlow 上有很多答案,但大多数都避开了您所问的原因,而且我怀疑您总是觉得它们部分不满意。
如果我们相信 Roy Fielding 的话,那么使用 HTTP/HTML 将大多数商业交互式客户端应用程序编写为 SOA RESTful/HATEOAS 是不可能的。我不能说,这可能在其他媒体中是可能的。
所以实际的答案是“在文档中查找它”和“用它中的应用程序知识编写你的客户”,并附带“忽略我们这样做违反菲尔丁规则的事实”。
我倾向于设计提供这种方法的 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 方式编写消费客户端,但这样做我使用的是响应体,菲尔丁说这不是他的本意。
不过,我会单独提供这个解释:
菲尔丁说:“我对将任何基于 HTTP 的接口称为 REST API 的人数感到沮丧。” (http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)。
请注意他如何如此刺耳地说“任何”基于 HTTP 的接口。
他的“讲座”中最相关的部分是:
"除了初始 URI(书签)和适合目标受众的标准化媒体类型集(即,任何可能使用该 API 的客户端都可以理解)之外,应该在没有任何先验知识的情况下输入 REST API 。由此点上,所有应用程序状态转换必须由客户端选择服务器提供的选项来驱动,这些选项存在于接收到的表示中或由用户对这些表示的操作暗示。转换可以由客户端对媒体的了解来确定(或限制)类型和资源通信机制,两者都可以即时改进(例如,按需编码)。[此处的失败意味着带外信息正在驱动交互而不是超文本。] “
他这样说是因为 HTTP/HTML 应用程序 URI媒体类型只是“text/html”,而其中的动词在哪里?没有一个。URI 无法告诉您使用/导航需要什么动词,因此您不能仅使用带内数据在客户端中动态构建“下一个”导航。
他解释说,他相信我们将 URI 呈现为包含“方法”的 CDATA 的一部分,或者 URI 的上下文会不言而喻地提供它,就像 FORM 元素一样。他明确反对 OpenSocialst REST API,声称它不是 RESTful。
这里:“带有HREF属性的<em>锚元素创建一个超文本链接,选择后,在与CDATA编码的HREF属性相对应的URI上调用检索请求(GET)。” 标识符、方法和媒体类型是正交关注点——媒体类型没有赋予方法意义。相反,媒体类型告诉客户端使用什么方法(例如,anchor 意味着 GET)或如何确定要使用的方法(例如,表单元素说要查看方法属性)。客户端应该已经知道方法的含义(它们是通用的)以及如何取消引用 URI。
请注意,他说客户应该已经知道这些方法的含义,他并没有说客户应该已经知道它们是什么——这就是您提出问题的原因。很多人都在为此苦苦挣扎,因为我们实际上并没有在大多数 SOA 环境中像这样构建我们的应用程序。
像很多工程师一样,我只是希望菲尔丁能做出澄清或重新声明,但他不仅没有这样做,他还向我们作为工程师发表了两条进一步的警告,加倍强调他的声明,说我们应该停止调用 API 的 RESTful 并接受我们正在构建 RPC。
我认为类似 JSON 元素的方法是一个合理的桥梁,但我无法回答我们使用请求正文来执行此操作的事实,而不是依赖媒体类型来暗示它。
最后,HTTP 中有一个较新的动词,称为 OPTIONS,对于给定的 URI,它将返回允许的动词动作列表。我认为菲尔丁参与编写了这个 HTTP 修订版。这将允许客户端在没有被禁止的内部应用知识的情况下一般地构建 URI 导航。但这在现实世界中我能想到三个问题:
- 您必须在您的服务聚合中编写一种机制,以便对您尝试返回的每个 URI 进行调用,并且由于大量数据包含许多 URI(HAL 中的 _links),这会在您的服务响应构造中添加大量额外的“跃点”。我们可能都会抱怨这一点。
- 几乎没有声称是 RESTful 的 SOA 站点实际上实现了一个 OPTIONS 动词方法调用,让您无论如何都可以进行此查询。
- 我们都会抱怨它为客户的处理增加了“不必要的”额外调用(尤其是在电子商务世界中),以及它倾向于将我们推到 SLA 要求之外。