REST 和多对多
REST and many to many
我的问题基于 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"
},
...
]
}
当我只想向团队添加一名球员时,这迫使我更新球员资源。此外,当我使用玩家资源将玩家添加到团队时,相应的团队资源会自动更新。根据 How to handle many-to-many relationships in a RESTful API?:
you don't want the alternate URL /players/5/teams/ to remain cached
在这种情况下,当我更新播放器 "John" 以从中删除团队 "Team 1" 时,teams/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" 或团队 "Team 1".
时,我们敞开心扉去合并冲突(和竞争条件)
关系的每一方都有自己的关系对象
GET /teams/1/players
产生类似
的东西
{
"_links": [
{
"rel": "player",
"href": "/players/john"
},
...
]
}
和
GET /players/john/teams
类似
{
"_links": [
{
"rel": "team",
"href": "/teams/1"
},
...
]
}
但是添加或删除一个可能仍会影响位于不同 URL(不共享根元素)的资源
我的问题
有没有解决我在这两个案例中提到的问题?
两种方法中哪一种是 'preferable' 或更纯粹的 REST?
我应该多认真对待 How to handle many-to-many relationships in a RESTful API? 中提到的约束:
you don't want the alternate URL /players/5/teams/ to remain cached
提前致谢!
您可以拥有以下内容
团队
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 补丁)(补丁 post 上的查询字符串...等虽然很少见,但有效)
PATCH /teams?player=john
[{
"op": "add",
"path": "/-",
"value": {
"href": "/team/dream"
}
}]
获取 john 的团队
GET /teams?player=john
{
"_links": {
},
"items": [
{
"href": "/teams/a-team"
},
{
"href": "/teams/dream"
}
]
}
John 离开了 A 队:
PATCH /teams?player=john
[{
"op": "remove",
"path": "/0"
}]
我的问题基于 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"
},
...
]
}
当我只想向团队添加一名球员时,这迫使我更新球员资源。此外,当我使用玩家资源将玩家添加到团队时,相应的团队资源会自动更新。根据 How to handle many-to-many relationships in a RESTful API?:
you don't want the alternate URL /players/5/teams/ to remain cached
在这种情况下,当我更新播放器 "John" 以从中删除团队 "Team 1" 时,teams/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" 或团队 "Team 1".
时,我们敞开心扉去合并冲突(和竞争条件)关系的每一方都有自己的关系对象
GET /teams/1/players
产生类似
的东西{
"_links": [
{
"rel": "player",
"href": "/players/john"
},
...
]
}
和
GET /players/john/teams
类似
{
"_links": [
{
"rel": "team",
"href": "/teams/1"
},
...
]
}
但是添加或删除一个可能仍会影响位于不同 URL(不共享根元素)的资源
我的问题
有没有解决我在这两个案例中提到的问题?
两种方法中哪一种是 'preferable' 或更纯粹的 REST?
我应该多认真对待 How to handle many-to-many relationships in a RESTful API? 中提到的约束:
you don't want the alternate URL /players/5/teams/ to remain cached
提前致谢!
您可以拥有以下内容
团队
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 补丁)(补丁 post 上的查询字符串...等虽然很少见,但有效)
PATCH /teams?player=john
[{
"op": "add",
"path": "/-",
"value": {
"href": "/team/dream"
}
}]
获取 john 的团队
GET /teams?player=john
{
"_links": {
},
"items": [
{
"href": "/teams/a-team"
},
{
"href": "/teams/dream"
}
]
}
John 离开了 A 队:
PATCH /teams?player=john
[{
"op": "remove",
"path": "/0"
}]