I am having troubles understanding how to use the “relationships” feature of the specifications with this scenario.
Reading the specs it looks to me like relationships is prepared to work with another table (resource) called in this case master-detail where the ids of the master are linked to the ids of the details. E.g.:
master-detail (master_id, detail_id)
So something like the following deletes the entry (1, 5) in master-detail leaving master and detail untouched.
DELETE /master/1/relationships/detail HTTP/1.1
{
detail = 5 // Read this as if it was correct format
}
Now in my structure I don’t have master-detail but just the table detail has the column master_id (null disallowed) as described above.
So to remove the detail 5 from master 1, the detail 5 has to be deleted from the detail table.
That means the above DELETE call in this case would just delete the entry with id 5 and master_id 1 in the detail table:
Is that how it should it work or should I forget about the relationships endpoint and just allow the user to delete the detail from the detail endpoint directly?
Thanks a lot for your reply. Indeed DELETE /detail/5 would implicitly delete the relationship as well.
I was more worried about the behavior of DELETE /master/1/relationships/detail. The section “Updating a relationship” states:
A server MUST respond to PATCH , POST , and DELETE
And then goes on saying:
If the client makes a DELETE request to a URL from a relationship link the server MUST delete the specified members from the relationship
So in my case when I DELETE the relationship (1,5) between master and detail inside my logic I would also need to delete the detail with id 5 altogether from my database. I think that is fine.
Now I guess the problem is POST /master/1/relationships/detail. The specs say:
If a client makes a POST request to a URL from a relationship link the server MUST add the specified members to the relationship
which in my case I cannot do since a new relationship means a new detail and a new detail is created with POST /detail. So I think the solution is I just need to disallow POST on such relationships (and the same for PATCH).
A “relationship object” MUST contain at least one of the following:
self : a link for the relationship itself (a “relationship link”). This link allows the client to directly manipulate the relationship. For example, removing an author through an article ’s relationship URL would disconnect the person from the article without deleting the people resource itself.
Additionally the following applies:
Note: A server may choose to delete the underlying resource if a relationship is deleted (as a garbage collection measure).
Therefore it is either possible to forbid the request or delete the resource detail as you already mentioned.
I’m not completely sure but the specification explicitely says that PATCH and DELETE can respond with a 403 forbidden. They didn’t mention this for the POST part. Therefore it could be that you have to support the post request.
However the specification does not forbid you to create a new detail via the relationship link. Therefore I would just implement it that way. Your case is special because you cannot even create a detail without a master resource. This way it does make even more sense to only allow creation of details via the relationship link instead of POST /detail.
I think you should implement it that way it matches your requirements. As long as your api is explorable, logical and responses with the right codes (403, 200, …) you are fine.