I have some questions regarging HAL and the expected behaviour for linking and unlinking resources. I can't find a guideline or specification for the following questions.
I try to make a simple example, hoping this help more people (it's a matter of rest and managing many to many relationship, found also as example here How to handle many-to-many relationships in a RESTful API?)
Think about a teams and player: a team has many player, a player belong to many teams. Rest services to obtain the list of player and teams are /players and /teams, and I can ask for specific team or player with /teams/{id} or /players/{id}.
So asking GET of /teams I will receive something like:
{
"count": 2,
"_embedded": {
teams: [{
"name": "red team",
"_links": {
"self": {"href": "/teams/RT"},
"players": {"href": "/teams/RT/players"}
}
}, {
"name": "blue team",
"_links": {
"self": {"href": "/teams/BT"},
"players": {"href": "/teams/BT/players"}
}
}]
},
_links: {
"self": {"href": "/teams"}
}
}
I'm thinking to use self link as key to identify in an unique way a resource so /teams/RT or /players/1 are the key representing the resources instance of Red Team and player 1.
If I would like to know players ot red team I will GET the link 'players' of red Team resource, so when I GET /teams/RT/players the resoult will be something like:
{
"count": "2",
"_embedded": {
players: [{
"name": "Jack",
"_links": {
"self": {"href": "/teams/RT/players/02"},
"myself": {"href": "/players/18"}
}
}, {
"name": "George",
"_links": {
"self": {"href": "/teams/RT/players/1"},
"myself?": {"href": "/players/3"}
}
}]
},
_links: {
"self": {"href": "/teams/RT/player"}
}
}
Questions (as client rest api consumer):
In the self of each embedded resource, I'm expecting a link useful to understand the relationship between the embedded resource and the related resource. It's also needed to unlink the resource from the list! (in this example remove Jack from Team Red ahouls be done with DELETE of /teams/RT/players/0. )
Is this correct? Or which should be the self href content? Should be more correct /teams/RT/players/18 or /teams/RT/players/0? (referring to the player id, or the id of relationship?)I would like to have a link to be able to distinguish/compare an embedded related resource, with a generic resource resulting from list of generic /resources/ service (or from any other relationship, eg. component of team Blu!!) In this example 'myself?' with href /players/18 it's a way to compare resources listed in /players GET. Do you know it there is any guide line about this? or did I mistake the meaning of self in the question 1.?
to link an existing resource (e.g. /players/8 ) to an existing team (e.g. /teams/BT) i can do in many way, but I don't know which could be the most effective one (I know it's a many to many relationship, so it could depends also from who is owning the relation):
- a: POST to teams/BT/players the resource of player 8. So It's should be added as a new relationship of team (and it could create multiple time it!).
- b: PUT to teams/BT/players a list of resources, which will replace the existint resources (verbose).
- c: PATCH to teams/BT/players with the only resource player 8
Note:
I do not want to introduce in the api service the meaning of 'membership', because is an abstraction of join table needed by db to maintain the many to many relationship. In this example the api consumer should only know that a team has a relationship players with player, and a player as a relationship teams to team.
The problem it's the same in one to many relationship, looking at it from father to children. E.g: a player has one or more pictures of him. so /players/3 has:
_links: { pictures: {href: '/players/3/pictures'}, self: {href: '/players/3'} }
If I want to add the picture identified by /pictures/193 to existing list of picture of player 3.... PATCH /players/3/pictures ? and list of picture of player 3 will be resolved by GET of players/3/pictures:
{
"count": 2,
"_embedded": {
pcitures: [{
"url": "http://server-storage.com/images/pic_scan_12.jpg",
"_links": {
"self": { "href": "/players/3/pictures/845"},
"myself?": {"href": "/pictures/845"}
}
}, {
"url": "http://server-storage.com/images_old/john_smith.jpg",
"_links": {
"self": { "href": "/players/3/pictures/293"},
"myself?": {"href": "/pictures/293"}
}
}]
},
_links: {
"self": {"href": "/players/3/pictures"}
}
}