Simple Master/Detail relationship

I have the following tables (which are also my resources):

master (id, name)
detail (id, master_id [not null], name)

Master can have many details. And then their corresponding endpoints:

/api/master
/api/master/{id}
/api/detail
/api/detail/{id}

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?

As fas as I understand the specification you should only DELETE directly via the resource url.

DELETE /detail/5

It doesn’t matter how your database is structured. It’s part of you backend to implement the correct behaviour to match the db structure.

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).

Does my thinking make sense?

Ok I see.

First of all the specification says:

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.

Thank you very much for your answer. You have pointed out a couple of important things.

From what I understand

  • POST /master/1/detail is not part of the specs.
  • POST /master/1/relationship/detail is allowed but only for creating a new resource identifier object (i.e.: only IDs no attributes).

So then this is the way I see I should proceed:

  • For creating a new detail:
  1. POST /master (this gives id e.g.:1)
  2. POST /detail (with relationship to master with Id 1, and gives id e.g. 5)
  • For deleting a detail, either of (Both delete the detail with id 5 from the DB)

a. DELETE /master/1/relationships/detail (giving id 5)
b. DELETE /detail/5

  • Then following should return some error:

a. POST /master/1/relationships/detail (because I cannot insert just an ID, I need to create the whole detail)

I guess the specs do not consider this case since they state:

the server MUST add the specified members to the relationship
So I should think about something here.

I guess I have it more or less clear now, thanks for the ideas.