代码之家  ›  专栏  ›  技术社区  ›  slaynerM

在Restful API中创建多对多关系的“正确”方法是什么

  •  3
  • slaynerM  · 技术社区  · 9 年前

    我试图找到最佳实践,以便在Restful API中创建多对多关系。用例非常简单,但我找不到 “干得好。

    在我们的模型中 小孩 与多对多关系相关的 守护者 在关系表中, 类型 (父母、保姆、紧急情况等)和 忙碌的 (布尔值)。

    守护者 现存的 小孩 ,但现有 守护者 可以与另一个链接 小孩 .

    今天,我们这样做

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

    这将创建 守护者 把它加到孩子身上。但是,使用这种方法,我们无法处理我要添加现有 守护者 小孩 下面是我找到的答案,以代表这一点,但我不知道哪一个是最好的(和restful的)方式(可能没有一个是好的…):

    解决方案1-保持端点不变

    但把非强制性 身份证件 现场 守护者 如果 身份证件 如果为空,则API必须创建ressource,否则只需检索它并在需要时更新值。

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

    # 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 
    }
    

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

    POST kids/{kidID}/kid-guardians/
    

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

    GET kids/{kidID}/guardians/
    

    监护人 与孩子有关,但不是

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

    将删除关系,而不是 守护者 .

    所以,你知道,我真的迷路了,非常感谢你的帮助。

    顺致敬意,

    2 回复  |  直到 9 年前
        1
  •  2
  •   Fabricio Rocha    9 年前

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

    我认为,通过使用到关系中每个成员的链接,而不是数字ID,您可以获得更加RESTful的结果。您可以在孩子和监护人表示中有一个类似“关系”的字段,其中URL+querystring用于检索他们的特定“警卫”,如果有人需要他们。

        2
  •  1
  •   slaynerM    9 年前

    我将使用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}/"
    }
    

    推荐文章