It seems dangerous to allow verbs other than GET on the “related” link. Because it always reflects the then current state, a client may do a GET on it and then want to change an attribute on the returned data, so it does a PATCH but if the target changed in between the two requests, the wrong resource may end up being updated.
Is the implementation left up to the server, e.g. make use of ETags so on any updates the client would have to present the ETag that was returned by the GET?
Isn’t the same race condition equally possible if a client has accessed a resource via its self
URL? i.e. If this is a problem for your domain then don’t you need to cater for it regardless of what link relation / URL was used to access a resource? I’m not sure why the related
URL should be a special case here.
It’s not quite the same. Imagine sending a DELETE on the “related” link which you thought represented /people/9 but by the time the DELETE gets processed the relationship got updated to now point to /people/10 so you end up deleting the “wrong” resource.
If you do it through the self link, then you always DELETE /people/9 even if the resource itself may have been updated between the GET and DELETE requests.
Now, for PATCH or PUT I agree that you still have the lost updates/stale data problem, but at least it’s on a resource you expect (/people/9), not on some other unexpected resource.
No, you don’t. Deleting via the self
link only removes the connection between the /people/9
resource and whatever resource had the relationship, and the /people/9
resource still exists.
I think there’s some misunderstanding here. If I send this exact request:
DELETE /people/9
The resource /people/9 better be gone if the request succeeds.
Yes, but the relationship links will never hold a URL like that. For the self
link the URL will be /someresource/someid/relationships/person
, and for the related
link the URL will be /someresource/someid/person
.
For /someresource/someid/relationships/person
the resource identifier object response will have a type
of “people” and an id
of “9”.
For /someresource/someid/person
the resource object response will again have a type
of “people” and an id
of “9”, and a resource level self
link of /people/9
If you want to delete a resource you need to do so via its URL (e.g. /people/9
), not via a relationship that happens to point to it.