在RESTful API中管理m:n关系的最佳做法

时间:2019-04-08 20:56:54

标签: rest api many-to-many

我正在设计一个API,并且我想注意RESTful方法。 因为在我的研究中,大多数类似的文章都是针对球员和球队的,所以我会坚持下去。 在这种情况下,一个球员一次只能拥有一个以上的球队,但必须至少拥有一个。 如果一个玩家附属于多个团队,则无法删除该玩家。

为此,如果您想创建一个播放器,则需要:

POST /teams/{id}/players

直接 POST /players 不会考虑到球员有一支球队,所以不允许。

如果要删除播放器,可以执行以下操作:

DELETE /players/{id}

这仅在玩家仅隶属于一个团队时才可行,但如果玩家在一个以上团队中则应拒绝(对于这种情况,您需要解散除一个团队以外的所有团队链接)。

现在,我有不同的方法来处理创建和删除团队与玩家之间的新链接:

  1. POST /teams/{id}/players/{id}
  2. PUT /teams/{id}/players/{id}
  3. POST /players-teams(在正文中具有players_id和teams_id)

a。 DELETE /teams/{id}/players/{id}

b。 DELETE /players-teams/{id}

关于不同解决方案的一些想法:

广告1. GET无法引用相同的信息

广告2。我没有提供关系的ID ...

广告3.我应提供GET /teams/{id}/players-teamsGET /players/{id}/players-teams-还是GET /players/{id}/teams-players

广告那不会删除播放器吗?

ad b。谁会知道关系的ID?

1 个答案:

答案 0 :(得分:2)

鉴于一个玩家可以存在于多个团队中,并且团队与玩家之间的关系可能会发生变化,所以我认为通常有两个单独的命名空间:

players/ <- list of all players
players/{id} <- a single player
teams/ <- list of all teams
teams/{id} <- a single team

缺少的是团队与球员之间的关系。解决此问题的一种好方法是让玩家表示为团队中的链接。这种团队资源的虚构表示:

{
   name: "team awesome",
   _links: {
     self : { href: "/teams/A" },
     players: [
       { href: "/players/1" },
       { href: "/players/2" },
     ]
  }
}

如果将关系表示为团队资源上的链接,则删除或添加玩家到团队的行为与向团队发送PUT资源并添加/删除这些链接相同。上面的格式使用HAL。

但是,如果您只想获得完整的玩家名单及其信息怎么办?绝对有可能将“团队中的所有球员”表示为单独的资源,也许在以下位置:

/teams/{id}/players

我仍然要确保此资源中的所有玩家都链接到/players/{id},而不是/team/{id}/players/{id}

即使不允许单个实体出现在系统中的多个URL上,也可能使用户感到困惑,因为它们看起来好像它们是单独的资源。