假设我有一个名为group
的资源,其代表如下:
{
"id": 1,
"name": "Superheroes"
"_links": {
"self": {
"href": "http://my.api.com/groups/1"
}
}
}
现在假设我要通过person
POST
创建一个新的/persons/1
实例。我应该将哪一个用于请求正文:
使用ID
{
"name": "Batman",
"groupId": 1
}
使用链接
{
"name": "Batman",
"group": "http://my.api.com/groups/1"
}
使用第一种方法,我直接访问id以查找相关资源或最终将id存储在数据库中,当我持久保存person
实例时。但是使用其他方法,我要么必须从URI中提取id,要么按照链接加载相关资源,然后找出它的id。我真的不想将URI存储在数据库中。
使用后一个选项,看到服务器控制URI的结构,我可以解析链接的id吗?回到服务器本身的链接看起来很奇怪,看到此时我们已经可以直接访问信息了(我们只需要id)。
总结一下,哪些选项最好?
答案 0 :(得分:2)
TL; DR:使用简单的ID。
更详细的解释:
一种直截了当的方法是通过使用有效负载/groups/1/persons
发送到{"name": "Batman"}
来创建一个人。
然而,虽然这种方法适用于简单的情况,但如果有2个资源需要引用,情况会变得复杂。让我们假设一个人也需要属于一家公司:
GET /persons/1
{
"name": "Batman",
"group": 1, // Superheros, available at /groups/1
"company": 5 // Wayne Enterprises, available at /companies/5
}
由于公司和群组之间没有任何关系,因此通过POST /groups/1/companies/5/persons
或/companies/5/groups/1/persons
创建人员在语义上并不正确。
因此,我们假设您要创建一个请求如下的人:
POST /persons
{
"name": "Batman"
"group": ???, // <--- What to put here?
"company": ??? // <--- What to put here?
}
这使我们回答你的问题:
易于使用。您的API应主要设计为易于使用。如果您设计公共API,则尤其如此。因此,选项2(使用链接,但解析出来的ID)已经用完,因为它会为您的API客户带来额外的工作。
构建搜索查询。如果您希望能够查询属于公司10
和组42
的人员,那么简单的ID会导致更易读,更少容易出错的网址。您认为以下哪一项更具可读性?
带有简单ID的网址:
GET /groups/42?company=10
或带有url-encoded链接的网址:
GET /groups/42?company=http%3A%2F%2Fmy.api.com%2Fcompanies%2F10
我不会低估可读性。您需要在各种卷发,日志,邮递员等中调试API多少次
开发链接需要在后端解析,而简单的ID可以直接使用。它不是关于性能,而是关于你必须投入的额外工作/测试。
端点维护。想象一下,您的API端点正在发展。您决定有一天切换到https或在网址中包含版本控制。如果由于某种原因它们依赖于链接的结构,这可能会破坏API客户端。此外,您可能想要检查后端上的链接解析是否正确完成。
Argumentum ab auctoritate 我知道这不是一个正确的论据,但如果你查看大型播放器的API,例如Twitter,Github或Stripe,他们都使用简单的ID。
HATEOAS。支持链接的一个常见理由是它与HATEOAS对齐。但是,据我所知,这与API响应中的其他链接有关,而不是在POST请求的有效负载中使用链接。
总而言之,我会选择简单的ID,因为我还没有听到过有利于链接的令人信服的论据,这会超过上述内容。
答案 1 :(得分:1)
根据我的经验,最好采用最简单的解决方案来提出请求。
生成新网址并解析它的过程似乎过多来获取资源,而发送所需项目的ID似乎要简单得多。
因此,我会以以下形式发送请求:
{ &#34;姓名&#34;:&#34;蝙蝠侠&#34;, &#34; group&#34;:1 }
答案 2 :(得分:1)
你在这里缺少两件重要的事情。
例如,带有SELECT INPUT的HTML FORM将是RESTful。我们在json中做的最接近的事情是json-ld和hydra。但是,如果你沉迷于hal,那么使用hyperagent forms或类似的东西。它永远不会成为标准,但如果兼容性不是问题,那就足够了。
要回答您的问题,您应该使用id,因为服务器知道如何解释它。客户端需要资源标识符,服务器只需要请求的uri部分,而不是正文。