Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTfully Nesting Resource Routes with Single Identifiers

In my Rails app I have a fairly standard has_many relationship between two entities. A Foo has zero or more Bars; a Bar belongs to exactly one Foo. Both Foo and Bar are identified by a single integer ID value. These values are unique across all of their respective instances.

Bar is existence dependent on Foo: it makes no sense to have a Bar without a Foo.

There's two ways to RESTfully references instances of these classes. Given a Foo.id of "100" and a Bar.id of "200":

  1. Reference each Foo and Bar through their own "top-level" URL routes, like so:

    • /foo/100
    • /bar/200
  2. Reference Bar as a nested resource through its instance of Foo:

    • /foo/100
    • /foo/100/bar/200

I like the nested routes in #2 as it more closely represents the actual dependency relationship between the entities. However, it does seem to involve a lot of extra work for very little gain. Assuming that I know about a particular Bar, I don't need to be told about a particular Foo; I can derive that from the Bar itself. In fact, I probably should be validating the routed Foo everywhere I go (so that you couldn't do /foo/150/bar/200, assuming Bar 200 is not assigned to Foo 150). Ultimately, I don't see what this brings me.

So, are there any other arguments for or against these two routing schemes?

Point of Clarification

I'm concerned mostly about RESTful updates/shows/deletes to particular Bars. For getting a list of Bars for a specific Foo (which is usually the "index" action in Rails) it makes perfect sense to have a nested route such as /foo/100/bar. The page at this route could just as easily link to /bar/x as /foo/100/bar/x though.

like image 754
Craig Walker Avatar asked May 23 '10 15:05

Craig Walker


People also ask

What are nested resources?

Nesting resources provide REST API consumers an easy and efficient way to manage data by allowing the consumer to send and receive only the required object. The nested resource must be a business object, that is, it must still represent a complete business object.

What is nested route?

Nested Routes are a powerful feature. While most people think React Router only routes a user from page to page, it also allows one to exchange specific fragments of the view based on the current route.

What is the difference between resources and resource in Rails?

Difference between singular resource and resources in Rails routes. So far, we have been using resources to declare a resource. Rails also lets us declare a singular version of it using resource. Rails recommends us to use singular resource when we do not have an identifier.


2 Answers

You're looking for shallow routes. As you pointed out, the idea of having a deeply nested route for things like creates, updates is unnecessary since you are targeting the desired record directly.

I have never actually done the shallow routing thing so I'll pass on the railscast episode where Ryan Bates explains it probably better than I could: 139 Nested Resources.

Edit: You can read up a little more on the guides for routing 3.8.4.

like image 119
theIV Avatar answered Oct 11 '22 05:10

theIV


As you already know, every item has to have a unique address. I would suggest that the shorter and easier the address is, the better for everyone involved - your routing code, your client apps, etc. If you can identify a Bar by its unique ID, I would probably specify only that in the URL.

You don't need to lose the semantic information about the Bar's assignment to a Foo, though. That can be part of the representation.

As an enhancement, you could allow the client to address Bar 200 as /foo/100/bar/200, but then redirect to the preferred /bar/200/ address, using, e.g., a 303 ("See Other") response.

like image 27
jwismar Avatar answered Oct 11 '22 05:10

jwismar