REST和许多人

时间:2015-03-12 10:23:39

标签: rest restful-architecture

我的问题基于How to handle many-to-many relationships in a RESTful API?,但我想继续接受已接受的答案。

假设我们在球员和球队之间有多对多的关系(就像上面提到的问题一样)。

据我了解,有几种方法可以使用REST资源对此进行建模:

有效负载包含对相关资源的引用

GET /players/john

产量

{
    "name": "John",
    "_links": [
        {
            "rel": "team",
            "href": "/teams/1"
        },
        {
            "rel": "team",
            "href": "/teams/4"
        }
    ]
}

GET /teams/1

产量

{
    "name": "Team 1",
    "_links": [
        {
            "rel": "player",
            "href": "/players/john"
        },
        ...
    ]
}

当我只想向玩家添加玩家时,这迫使我更新玩家资源。此外,当我使用播放器资源向玩家添加玩家时,相应的团队资源会自动更新。根据{{​​3}}:

  

您不希望备用网址/玩家/ 5 /球队/保持缓存

在这种情况下,当我更新播放器" John"时,团队/ 1可能会保持缓存状态。删除团队"团队1"从它!

该关系被建模为另一种资源

GET /teams/1

产量

{
    "name": "Team 1",
}

GET /players/john

产量

{
    "name": "John",
}

最后,

GET /relationships

产量

    [
    {
        "_links": [
            {
                "rel": "player",
                "href": "/players/john"
            },
            {
                "rel": "team",
                "href": "/teams/1"
            }
        ]
    },

    ...
]

这样,我可以创建和删除关系,而不会影响播放器资源和团队资源。但是当我删除/ players / john时,是否应该自动删除匹配关系?如果是这种情况,则违反与上述相同的规则。如果不是这种情况,我们需要手动删除这些关系,这是很多工作,我不想让我的API的消费者负担。

此外,如果我们想要更新团队某个玩家" John"在,我们需要删除一些关系并添加其他关系。当其他人正在编辑玩家时,我们将自己开放合并冲突(和竞争条件)" John"或团队"团队1"。

关系的每一方都有自己的关系对象

GET /teams/1/players

产生类似

的东西
{
    "_links": [
        {
            "rel": "player",
            "href": "/players/john"
        },
        ...
    ]
}

GET /players/john/teams

类似

{
    "_links": [
        {
            "rel": "team",
            "href": "/teams/1"
        },
        ...
    ]
}

但添加或删除一个可能仍然会影响位于不同URL(不共享根元素)的资源

我的问题

在这两种情况下,我提到的问题是否存在?

这两种方法中哪一种更可取?'或更纯粹的REST?

我应该认真对待How to handle many-to-many relationships in a RESTful API?中提到的约束:

  

您不希望备用网址/玩家/ 5 /球队/保持缓存

提前谢谢!

1 个答案:

答案 0 :(得分:1)

您可以拥有以下

GET /teams/dream

{
    "_links": {
        "self": {
            "href": "/teams/dream"
        }
        "players": {
            "href": "/players?team=dream"
        }
    },
    "name": "Dream"
}

播放器

GET /player/john

{
    "_links": {
        "self": {
            "href": "/player/john"
        },
        "teams": {
            "href": "/teams?player=john"
        },
    },
    "name": "John",
}

John的团队

GET /teams?player=john

{
    "_links": {
    },
    "items": [
        {
            "href": "/teams/a-team"
        }
    ],
}

将john添加到梦之队,(例如使用json补丁)(补丁帖子上的查询字符串......等虽然很少见,但是有效)

PATCH /teams?player=john

[{
    "op": "add",
    "path": "/-",
    "value": {
        "href": "/team/dream"
    }
}]

获得约翰的团队

GET /teams?player=john

{
    "_links": {
    },
    "items": [
        {
            "href": "/teams/a-team"
        },
        {
            "href": "/teams/dream"
        }
    ]
}
约翰离开了一个团队:

PATCH /teams?player=john

[{
    "op": "remove",
    "path": "/0"
}]