【问题标题】:What's the "right" way to create a many-to-many relationship in a Restful API在 Restful API 中创建多对多关系的“正确”方式是什么
【发布时间】:2016-10-31 20:15:25
【问题描述】:

我试图找到最佳实践,以便在 Restful API 中创建多对多关系。用例非常简单,但我找不到真正的“正确”方法。

在我们的模型中,我们有与 Guardian 的多对多关系相关的 Kid。在关系表中,我们有 2 个额外的参数,type(parent、nanny、emergency 等)和 active(布尔值)。

您只能将 Guardian 添加到现有 Kid,但现有 Guardian 可以与另一个 Kid 链接>.

今天,我们就是这样做的

POST kids/{kidID}/guardians
{
    "type": "parent"
    "active": false 
    "guardian": {
        "first_name": "foo"
        "last_name": "bar"
    }
}

这将创建 Guardian 并将其添加到 Kid。但是,使用这种方法,我们无法处理我想将现有 Guardian 添加到 Kid 的情况。这是我为了代表这一点而找到的答案,但我不知道哪一个是最好的(和宁静的)方式(也许没有一个是好的......):

解决方案 1 - 保持端点为今天

但是给 guardian 设置一个非强制性的 id 字段。如果 id 为空,API 必须创建资源,否则只需检索它并在需要时更新值。

POST kids/{kidID}/guardians/
{
    "type": "parent"
    "active": false 
    "guardian": {
        "id": "ab65f263-dd3d-bbc6-8b7b-57a3b4b26c21"
    }
}

解决方案 2 - 在 2 次调用中中断此端点

# Create the Guardian
POST guardians/
{
    "first_name": "foo"
    "last_name": "bar"
}

# This method can only "link" the models
POST kids/{kidID}/guardians/
{
    "type": "parent"
    "active": false 
    "guardian_id": "ab65f263-dd3d-bbc6-8b7b-57a3b4b26c21"
}

[已编辑] 解决方案 2.5 - 创建与 PUT 的关系

和以前一样,你必须创建监护人,但为了添加你所做的关系

PUT kids/{kidID}/guardians/{guardianID}
{
    "type": "parent"
    "active": false 
}

辅助解决方案:在第二种选择中,我们可以通过以下方式更改资源的URI:

POST kids/{kidID}/kid-guardians/

因为它并没有真正发布“监护人”资源,而是儿童监护人资源(关系)。我不太喜欢它,因为使用旧的 URI 我们可以更容易地假设

GET kids/{kidID}/guardians/

会给你所有与孩子有关的监护人,但不是那个

DELETE kids/{kidID}/guardians/{guardianID}

将删除关系而不是 Guardian

如您所知,我真的很迷茫,希望您的帮助。

最好的问候,

【问题讨论】:

    标签: rest entity-relationship restful-architecture restful-url nested-resources


    【解决方案1】:

    难道不能为关系本身创建第三类资源,例如“守卫”,而不是从属于其他资源的实例吗?这似乎是处理数据库中 n 对 n 关系的推荐和常用方法。

    GET /guards?kid="Johnny" 会给你一个关系列表,你可以使用它来获取它的所有监护人。 GET /guards?guard="Kelly",你可以猜到。 /kids/guards 将仅保留有关资源本身的数据,并且可能比您必须保留关系数据作为它们的一部分更容易维护。

    我认为您可以通过使用指向关系中每个成员的链接而不是数字 ID 来获得更多的 RESTful。您可以在孩子和监护人表示中使用“关系”之类的字段,其中包含检索其特定“监护人”所需的 URL+查询字符串,可能有人需要它们。

    【讨论】:

    • 感谢您的回答。我没有保留这种方法有几个原因:1 - 对我来说,这听起来更像是数据库思维而不是 REST。 2 - guards EP 真的是资源吗?所有 CRUD 似乎对我都没有用,我真的需要 GET guards/{guardID} 吗? 3 - 我们能否不使用您的 EP kids/{kidID}/guardians/ 来检索关系。再次感谢您的帮助,也许是最好的解决方案,我对我的 RESTful 观点完全错误
    • 1 - 我不是 DB 或 REST 方面的专家,但这里看起来像是 modelling_ 的问题,如果关系是什么对于业务模型很重要,它确实是 API 中的潜在资源。 2 - 如果您想获取有关特定关系的数据,并且这种关系可以及时来去,GET/POST/PUT/DELETE /guards/{id} 很有意义,似乎更易于维护,甚至可以隐藏在客户端应用程序中,在您的#3 想法背后(下一个)。 3 - 你可以创建一个这样的别名,当然,同样/guardians/{id}/kids。顺便说一句,我不知道“EP”是什么意思:)运气!
    【解决方案2】:

    我会选择 Fabricio Rocha 的答案,这样实现:

    POST guardian-kids/
    {
        "type": "parent",
        "guardian": {
            "id": "{guardianId}"
        },
        "kid":{
            "id": "{kidId}"
        }
    }
    

    如果你想找回守护者孩子

    GET guardian-kids/{GuardianKidId}
    {
        "type": "parent",
        "guardian": {
            "id": "{guardianId}",
            "url": "guardians/{guardianId}/"
        },
        "kid": {
            "id": "{kidId}",
            "url": "kids/{kidId}/"
        },
        "url": "guardian-kids/{GuardianKidId}/"
    }
    

    我也做了这两个端点(你只能 GET 那些)

    GET kids/{kidId}/guardian-kids
    {
        "type": "parent",
        "guardian": {
            "id": "{guardianId}",
            "url": "guardians/{guardianId}/"
        },
        "kid": {
            "id": "{kidId}",
            "url": "kids/{kidId}/"
        },
        "url": "guardian-kids/{GuardianKidId}/"
    }
    
    GET guardians/{guardianId}/guardian-kids
    {
        "type": "parent",
        "guardian": {
            "id": "{guardianId}",
            "url": "guardians/{guardianId}/"
        },
        "kid": {
            "id": "{kidId}",
            "url": "kids/{kidId}/"
        },
        "url": "guardian-kids/{GuardianKidId}/"
    }
    

    我在其他方法中看到的“问题”是 /kids/{kidID}/guardians/ 和 /guardians/ 将不代表同一种资源但具有相同的名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      相关资源
      最近更新 更多