小编典典

如何在 RESTful API 中处理多对多关系?

all

想象一下,您有两个实体 PlayerTeam
,其中玩家可以在多个团队中。在我的数据模型中,每个实体都有一个表,以及一个用于维护关系的连接表。Hibernate可以很好地处理这个问题,但是我如何在RESTful
API 中公开这种关系呢?

我可以想到几种方法。首先,我可能让每个实体都包含另一个实体的列表,因此 Player 对象将具有它所属的 Teams 列表,并且每个 Team
对象将具有属于它的 Player 列表。因此,要将玩家添加到团队中,您只需将玩家的表示发布到端点,例如
POST/playerPOST
/team,并使用适当的对象作为请求的有效负载。这对我来说似乎是最“RESTful”的,但感觉有点奇怪。

/api/team/0:

{
    name: 'Boston Celtics',
    logo: '/img/Celtics.png',
    players: [
        '/api/player/20',
        '/api/player/5',
        '/api/player/34'
    ]
}

/api/player/20:

{
    pk: 20,
    name: 'Ray Allen',
    birth: '1975-07-20T02:00:00Z',
    team: '/api/team/0'
}

我能想到的另一种方法是将关系本身作为一种资源公开。因此,要查看给定团队中所有玩家的列表,您可能会执行
GET/playerteam/team/{id}或类似的操作并返回 PlayerTeam
实体列表。要将玩家添加到团队,/playerteam请使用适当构建的 PlayerTeam 实体作为有效负载进行 POST。

/api/team/0:

{
    name: 'Boston Celtics',
    logo: '/img/Celtics.png'
}

/api/player/20:

{
    pk: 20,
    name: 'Ray Allen',
    birth: '1975-07-20T02:00:00Z',
    team: '/api/team/0'
}

/api/player/team/0/:

[
    '/api/player/20',
    '/api/player/5',
    '/api/player/34'
]

对此的最佳做法是什么?


阅读 224

收藏
2022-04-08

共1个答案

小编典典

在 RESTful
接口中,您可以通过将这些关系编码为链接来返回描述资源之间关系的文档。因此,可以说一个团队/team/{id}/players/player/{id}一个文档资源(/player/{id}/teams)
是指向玩家所属球队的链接列表。漂亮而对称。您可以轻松地在该列表上进行地图操作,甚至为关系提供自己的 ID(可以说它们有两个
ID,具体取决于您是考虑团队优先还是玩家优先的关系),如果这会让事情变得更容易.
唯一棘手的一点是,如果您从一端删除它,您必须记住从另一端删除关系,但是通过使用底层数据模型严格处理这个问题,然后让 REST 接口成为该模型将使这更容易。

关系 ID 可能应该基于 UUID 或同样长且随机的东西,而不管您为球队和球员使用的任何类型的 ID。这将允许您在关系的每一端使用与 ID 组件相同的
UUID,而不必担心冲突(小整数 没有
这种优势)。如果这些成员关系除了以双向方式将球员和球队联系起来之外还有其他任何属性,那么他们应该有自己的身份,独立于球员和球队;然后,玩家»团队视图 (
/player/{playerID}/teams/{teamID}) 上的 GET 可以执行 HTTP 重定向到双向视图 (
/memberships/{uuid})。

我建议使用XLink xlink:href属性在您返回的任何 XML
文档中编写链接(当然,如果您碰巧正在生成 XML) 。

2022-04-08