我是构建HTTP API的初学者,我似乎对REST API和Web API之间的差异感到困惑。我在网络上阅读了更多有关该内容的信息,这似乎加剧了混乱。我猜想Fielding与此链接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)上尝试使用它作为我的用户名,它按照HATEOAS原则返回了所有相关链接。
它是最好的现实世界API之一,它接近REST规范,恕我直言。尽管我无法理解哪个URI支持哪种操作以及在使用REST API的情况下如何找到它(如果我是它的使用者),或者在我托管该API的情况下如何告诉使用者?
一个不错的博客是https://www.e4developer.com/2018/02/16/hateoas-simple-explanation/。
大多数博客中都给出了所有其他示例,只是告诉您使用JSON作为REST API,将所有内容都作为Resource成为REST API,并使用HTTP动词将CRUD操作用作REST API。我发现这些都不是真的。
在我的工作中,我使用Sendgrid的Web API向客户端发送电子邮件,他们将其称为Web API,而不是REST,我认为这很正确。
有人可以举例说明两者之间的区别吗?
如果Github API是REST API的正确示例,那么我们如何才能知道哪个URI支持哪些操作作为媒体类型呢?
答案 0 :(得分:1)
唯一可以告诉您支持什么的资源是资源本身。资源提供的有关其他资源支持的任何信息纯粹是建议性的。找出问题的唯一真实方法是尝试并处理成功/失败。这是因为接受的请求可能会每分钟更改一次(例如删除)。
如果您的API可以在Web浏览器中导航并且可以提交表格(客户端对起始API和URL格式一无所知,并且不知道您的API),并且假设text / html是API的可协商表示形式,那么它就是RESTful。即使它无法在浏览器中导航,也可以是RESTful的,但这很难证明。
答案 1 :(得分:1)
您是对的,有很多困惑。专家通常将“真正的” REST API称为HATEOAS或超媒体驱动的API,以避免混淆。大部分要做自称REST api的API都不是。
因此,在与其他工程师讨论REST api时,首先弄清每个人对REST而不是REST的理解是有帮助的。他们并不是不知道的坏工程师,“ REST”这个词本身就是命脉,我想说HATEOAS可能更多是利基技能。
我同意尼古拉斯·尚克(Nicholas Shank)的回答,在许多情况下,普遍要弄清楚例如DELETE
是否起作用,实际上是发出DELETE
,然后看看它是否起作用。 / p>
但这并不总是有用的,因为许多构建API的人都希望如果仍然无法使用,则不显示“删除”按钮。
那么告诉客户DELETE
可用的合理方法是什么? HTTP标准实际上确实具有 Allow 标头,您可以使用该标头找出在给定端点上起作用的方法。要找出它们是什么,您可以发出一个OPTIONS
请求。并非每个框架都支持开箱即用,但这是这样做的合法方法。
另一种提前告知客户端的方法是将此信息嵌入到您正在访问的资源中。几个例子:
DELETE
根本无法使用的情况下,这可能会很好地工作,但在不同用户可能具有不同访问级别并且某些人可以使用{{1}的情况下,这不能真正帮助您},其他人则不能。最终,一种良好的HATEAOS格式不仅会返回有关资源和与他人之间的关系的信息,还会提供一组可以采取的潜在措施。 HATEAOS中大多数 的REST API往往不这样做,但是HTML就是最好的例子。如果没有链接,按钮或表单可以执行操作,则用户将无法发现该操作。
DELETE
{
"_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" },
]
}