我是构建HTTP API的初学者,我似乎对REST API和Web API之间的区别感到困惑。我在网上读到的更多,混乱似乎加起来了。我想菲尔丁有与此链接相同的问题 http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
我在工作中构建了一个HTTP API,认为我构建了一个REST API,因为无论我在哪里阅读,他们都在构建Web/HTTP API并称之为REST。
当我发现一个遵循HATEOAS原则的API是Github REST API https://api.github.com。我尝试在Github(GET https://api.github.com/users/vvs14)上使用它作为我的用户名,它根据HATEOS原则返回了所有相关链接。
恕我直言,它是接近 REST 规范的最佳现实世界 API 之一。虽然我无法理解哪个 URI 支持对它执行什么操作,以及如果我是它的使用者,如何在任何 REST API 的情况下找到它,或者如果我托管 API,如何告诉消费者?
一个关于它的好博客是 https://www.e4developer.com/2018/02/16/hateoas-simple-explanation/。
大多数博客中都给出了所有其他示例,只是告诉使用JSON作为REST API,将所有内容作为资源作为REST API,并使用HTTP动词进行CRUD操作成为REST API。我不认为这些是真的。
在我的工作中,我使用Sendgrid的Web API向客户发送电子邮件,他们称之为Web API,而不是REST,我认为这是非常正确的。
谁能用例子来澄清这两者之间的区别?
如果 Github API 是 REST API 的正确示例,我们怎么知道哪个 URI 支持哪些操作,因为此处未提及媒体类型?
你是对的,有很多混乱。专家通常将"真正的"REST API称为HATEOAS或超媒体驱动的API,以避免这种混淆。大多数自称为 REST API 的 API 通常不是。
因此,当与其他工程师讨论 REST API 时,首先澄清每个人认为 REST 而不是 REST 是有帮助的。他们不是不知道的坏工程师,"REST"这个词只是有自己的生命,我想说HATEOAS可能更像是一种利基技能。
我同意尼古拉斯·尚克(Nicholas Shank)的回答,即在许多情况下,确定例如DELETE
是否有效的通用方法是实际发布DELETE
,然后查看它是否有效。
不过,这并不总是有帮助的,因为许多构建 API 的人都希望不显示"删除"按钮,如果它无论如何都不起作用。
那么,告诉客户DELETE
可用的合理方法是什么?HTTP 标准实际上确实有一个Allow标头,您可以使用它来找出哪些方法在给定端点上有效。要了解这些是什么,您可以发出OPTIONS
请求。并非每个框架都支持开箱即用,但这是一种合法的方法。
提前告诉客户端的另一种方法是将此信息嵌入到您正在访问的资源中。举几个例子:
- 链接提示是一个互联网标准草案,可以在各种不同的地方提供这些提示,例如HAL,HTTP Link标头或其他。它基本上建议了此信息的通用格式。
- 如果你使用像OpenAPI这样的东西,你可以在你的API规范中添加哪些方法可以工作,哪些方法不会起作用。这适用于您知道
DELETE
根本无法正常工作的情况,但是在不同的用户可能具有不同级别的访问权限的情况下,它不会很好地帮助您,有些人可以使用DELETE
而其他人不能。 - 您可以通过将此信息表示为一组权限,以您自己的格式嵌入此信息,也可以采用应用程序理解的 JSON 格式来解释是否可以执行某些操作。
- 某些 HATEAOS 格式明确嵌入了有关可以通过操作执行哪些操作的信息。一个很好的例子是警报器格式。HAL本身没有这个。
最终,一个好的HATEAOS格式不仅会向其他人返回有关资源和关系的信息,而且还会给出一组可以采取的潜在操作。大多数 HATEAOS的REST API 往往不会这样做,但 HTML 是这样做的最好例子。如果没有用于执行操作的链接、按钮或表单,则用户无法发现该操作。
嵌入在 HAL 中的链接提示示例
{
"_links": {
"self": {
"href": "/orders/523",
"hints": {
"allow": ["GET", "DELETE"],
}
}
}
}
警笛示例
{
"class": [ "order" ],
"properties": {
"orderNumber": 523,
},
"actions": [
{
"name": "delete-order",
"title": "Delete Order",
"method": "DELETE",
"href": "/orders/523",
}
],
"links": [
{ "rel": [ "self" ], "href": "/orders/523" },
]
}
选项响应
HTTP/1.1 200 OK
Allow: GET, DELETE
唯一可以告诉你它支持什么的资源是资源本身。资源为您提供的有关其他资源支持的任何信息纯粹是建议性的。找出答案的唯一真正方法是尝试并处理成功/失败。这是因为接受的请求可能会每分钟更改(例如删除)。
如果您的 API 可以在 Web 浏览器中导航和表单提交(一个客户端除了起始 URL 和 HTML 格式之外对您的 API 一无所知),并且假设 text/html 是您的 API 的可协商表示,那么它就是 RESTful。即使它无法在浏览器中导航,它也可以是 RESTful 的,但这更难证明。