mlst
mlst

Reputation: 3431

What is the RESTful way to design URL that returns parent of a child resource?

I am modeling blogging REST API which has resources Blog, Post and Comment with following URLs:

/api/blogs
/api/blogs/{blogId}
/api/blogs/{blogId}/posts

and I create separate endpoint for all Posts in and their Comment`s:

/api/posts
/api/posts/{postId}
/api/posts/{postId}/comments

Given that I have postId, what is the RESTful way to get Blog for a specific Post? I have three ideas:

1. /api/posts/{postId}/blog
2. /api/blogs/parent-of-post/{postId}
3. /api/blogs?postId={postId}

To me the 1. URL looks more "prettier" but the 2. option looks more "logical" since that endpoint (eg. /api/blogs/*) is generally for blogs resources.

The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter. Eg. without parameter /api/blogs returns a collection of Blog resources, while with parameter postId it would return just single instance of Blog. I am not sure if this is good thing to do (especially because I am using ASP.NET Core and C# which has strongly typed return objects, so implementation might be awkward).

Upvotes: 0

Views: 1284

Answers (1)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57257

what is the RESTful way to get Blog for a specific Post?

Real answer: anything you want.

REST doesn't care what spelling conventions you use for your resource identifiers. As long as your identifiers conform to the production rules described by RFC 3986, you are good to go.


/api/blogs?postId={postId}

This is a perfectly normal choice, and turns out to be a really convenient one when you want to use general purpose web browsers, because HTML forms already have standards that make it easy to create URI with this shape.

Your other two choices are fine; they lose a point for not being HTML form friendly, but it's still easy enough to describe these identifiers using a URI template.


The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter

General purpose API consumers do NOT assume that two resources are alike just because the spellings of their identifiers overlap each other.

Which is to say, from the outside, there is no implied relationship between

/api/blogs
/api/blogs/1
/api/blogs?postId=2

so the fact that they return different bodies really isn't going to be a surprise to a general purpose consumer.

Now, your routing framework may not support returning different types from the handlers for these resources (or, more likely, may not have any "nice" way to do the routing automatically), but that's an implementation detail deliberately hidden behind the REST API facade.

Similarly, the human beings that read your access log might prefer one spelling to another, to reduce their own cognitive load.

Upvotes: 1

Related Questions