我尝试找到最佳实践,以便在Restful API中创建多对多关系。用例非常简单,但我无法真正找到“正确的”方式。
在我们的模型中,我们有 Kid 与 Guardian 的多对多关系相关。在关系表中,我们有2个额外的参数, type (父,保姆,紧急等)和活动(布尔)。
您只能将 Guardian 添加到现有的 Kid ,但现有的 Guardian 可以与其他 Kid 链接>
今天,我们这样做
POST kids/{kidID}/guardians
{
"type": "parent"
"active": false
"guardian": {
"first_name": "foo"
"last_name": "bar"
}
}
这会创建 Guardian 并将其添加到Kid。但是,通过这种方法,我们无法处理我想将现有 Guardian 添加到 Kid 的情况。在这里我找到的答案是为了表示这一点,但我不知道哪一个是最好的(和宁静的)方式(可能没有一个是好的......):
解决方案1 - 将端点保持为今天
但是将非强制性 id 字段添加到监护人。如果 id 为空,则API必须创建ressource,否则只需检索它并在需要时更新值。
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/
会给你所有与孩子相关的 Guardians ,但不是
DELETE kids/{kidID}/guardians/{guardianID}
将删除关系,而不是 Guardian 。
据你了解,我真的迷路了,非常感谢你的帮助。
致以最诚挚的问候,
答案 0 :(得分:1)
不可能为关系本身创建第三类资源,例如“guard”,而不是从属于其他资源的实例?它似乎是处理数据库中n到n关系的推荐和常用方法。
GET /guards?kid="Johnny"
会为您提供一系列关系,您可以使用这些关系来获取所有监护人。 GET /guards?guard="Kelly"
,你可以猜到。 /kids
和/guards
只会保留有关资源本身的数据,并且可能比您必须将关系数据作为其中一部分更容易维护。
我认为通过使用指向关系的每个成员的链接而不是数字ID,您可以获得更多RESTful。并且您可以在孩子和监护人表示中使用“关系”这样的字段,并使用URL +查询字符串来检索他们需要的特定“警卫”。
答案 1 :(得分:1)
我将使用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 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 /不会代表相同类型的资源,但具有相同的名称。