问题 REST API - 包括相关对象详细信息或仅包含ID


什么是更好的设计实践?

如果我有对象A并且它包含一些相关对象,例如我有一个汽车对象,它有各种类型。

我应该要求 api.example.org/cars/1 仅对这些资源的ID进行响应(因此,如果有人需要有关它们的详细信息,则需要另外的API调用 api.example.org/type/1

{
    "id": 1,
    "name": "Some Car",
    "types": [
        1,
        2
    ]
}

或提供有关这些资源的详细信息

{
    "id": 1,
    "name": "Some Car",
    "types": [
        {
            "id": 1,
            "name": "Some Type",
            "something": "Blah"
        },
        {
            "id": 2,
            "name": "Some Type",
            "something": "Blah"
        }
    ]
}

或者提供可选参数,如“displayAll”,然后提供带有参数名称的数组,这些参数应该在一次API调用中检索(在这种情况下) 类型)。


1523
2018-02-18 01:32


起源



答案:


这涉及REST的核心原则之一,称为HATEOAS(超媒体作为应用程序状态的引擎)。

对象ID对客户来说毫无用处且毫无意义。你怎么用他们?将它们送到搜索功能?构造一个新的URI,并将它们附加到它的末尾?拨打1-800电话,询问如何使用它们?将它们打印在纸上并邮寄给政府机构,帮助API客户找到他们的下一步骤?

只需返回完整的URI。给客户端的ID应始终是URI - 它是唯一标识有问题资源的东西,可用于检索,更新或删除它。


10
2018-02-18 17:31



但问题是:如果你没有将根网址和id分开,如果根网址发生变化(v1到v2,或者诸如此类),那么之前的所有链接都会被破坏,不是吗?是否没有用于集中根来指导客户端的用例? - Alex Moore-Niemi
保持极少数稳定的“酷”URI,这些URI永远不会改变,并使其下面的所有其他URI可通过超链接导航到达。客户端应用程序应编码为从Cool入口点URI开始,并通过导航这些关系找到所需的资源。这是HATEOAS的核心部分 - 您的大多数URI结构应该随着需求的变化而灵活变化,但不会影响现有应用程序。 - Brian Kelly


答案:


这涉及REST的核心原则之一,称为HATEOAS(超媒体作为应用程序状态的引擎)。

对象ID对客户来说毫无用处且毫无意义。你怎么用他们?将它们送到搜索功能?构造一个新的URI,并将它们附加到它的末尾?拨打1-800电话,询问如何使用它们?将它们打印在纸上并邮寄给政府机构,帮助API客户找到他们的下一步骤?

只需返回完整的URI。给客户端的ID应始终是URI - 它是唯一标识有问题资源的东西,可用于检索,更新或删除它。


10
2018-02-18 17:31



但问题是:如果你没有将根网址和id分开,如果根网址发生变化(v1到v2,或者诸如此类),那么之前的所有链接都会被破坏,不是吗?是否没有用于集中根来指导客户端的用例? - Alex Moore-Niemi
保持极少数稳定的“酷”URI,这些URI永远不会改变,并使其下面的所有其他URI可通过超链接导航到达。客户端应用程序应编码为从Cool入口点URI开始,并通过导航这些关系找到所需的资源。这是HATEOAS的核心部分 - 您的大多数URI结构应该随着需求的变化而灵活变化,但不会影响现有应用程序。 - Brian Kelly


我更喜欢选项1的无参数版本,但我更倾向于返回类型资源的位置,以便客户端可以选择是否检索这些资源。

否则,我们不会浏览文档。相反,我们将依赖于一些带外数据,例如事先知道类型的路径。

{
    "id": 1,
    "name": "Some Car",
    "types": [
        {
            "location": "api.example.org/type/1"
        },
        {
            "location": "api.example.org/type/2"
        }
    ]
}

2
2018-02-18 10:54