borjagvo
borjagvo

Reputation: 2081

API - do I need the parent resource?

A person can have many reviews. My endpoint to CREATE a new review is:

post /person/{id}/reviews

How about the endpoint to UPDATE a review? I see two options:

  1. Stick to the parent resource: patch /person/{person_id}/reviews/{id}
  2. Only have reviews in the URI: patch /reviews/{id}

I could be sold on using either of them:

  1. It's consistent with the previously defined endpoint, but {person_id} is not needed.
  2. It's 'efficient' as we're not specifying a parameter ({person_id}) that is not really needed. However, it breaks the API convention.

Which one is preferable and why?

Upvotes: 2

Views: 673

Answers (2)

Rich Steinmetz
Rich Steinmetz

Reputation: 1291

In terms of API design, without knowing too much detail about OP's situation I'd walk along these guideposts:

Only have reviews in the URI: patch /reviews/{id} It's 'efficient' as we're not specifying a parameter ({person_id}) that is not really needed. However, it breaks the API convention

The "efficiency" allows for a more flexible design. There's no existing API convention broken at this point. Moreover, this approach gives you the flexibility to avoid the need of always needing the parent resource ID whenever you display your items.

Stick to the parent resource: patch /person/{person_id}/reviews/{id} It's consistent with the previously defined endpoint, but {person_id} is not needed.

The consistency aspect here can be neglected. It's not beneficial to design endpoints similarly to other endpoints just because the previous ones were designed in a certain way.

The key when deciding one way or the other is the intent you communicate and the following restrictions that are put on the endpoint.

The crucial question here is:

Can the reviews ever exist on their own or will they always have a parent person?

If you don't know for sure, go for the more flexible design: PATCH /reviews/{id}

If you do know for sure that it always will be bound to a particular person and never can have a null value for person_id in the database, then you could embed it right into your endpoint design with: PATCH /person/{person_id}/reviews/{id}

By the way, the same is true for other endpoints, like the creation endpoint POST /person/{person_id}/reviews/{id}. Having an endpoint like this removes the flexibility of creating reviews without a person, which may be desirable or not.

Upvotes: 1

Evert
Evert

Reputation: 99571

The client shouldn't have to know about ids at all. After a client creates the review, the response should include the URI to the new review like this:

HTTP/1.1 201 Created
Location: /person/4/reviews/5

The client now has the full URL to the review, making it completely irrelevant how it looks like and what information is here.

Don't forget that the URL itself is a system to create globally unique IDs, that embed not just it's own unique identity but also information on how to access the data. If you introduce a separate 'id' and 'person_id' field you are not taking advantage of how the web is supposed to work.

Upvotes: 1

Related Questions