Skip to main content

API design/routing with nested resources

Tips • Asked by Sean Washington

Hey all!

I'm just curious, how would you surface the ability to create nested items in an API? Say you have a model Post that has_many observations.

I have my base routes for both Post and Observations, but in thinking about a client using the API, they'd probably need the UI to have the post form and observation forms in the same view since observations are directly tied to posts. One problem is that when you're adding a post, it's new so we can't just create an observation by sending a POST to /api/v1/observations because we don't have a post_id to assign to yet. I suppose someone making the client (my future self) could force the creation of a post before adding observations to it, but that feels more like a limitation than anything.


Hey Sean!

What you might consider doing here is accepting nested attibutes on the create Post action in your API. That way they can submit a post and include some preliminary records for observations all together. Those are often super convenient things so that your API users don't have to make two API requests first to posts and then to observations afterwards.

The other thing is I would suggest using nested routes for this as well. Think of these two routes:

resources :posts do
  resources :observations
end

resources :observations

In the top section that's nested, you can get observations attached to a specific post really easily by asking for the /api/v1/posts/1/observations url. As someone using your API, I know at a glance that it would give me only observations for that specific post.

You might also want to offer the ability to operate across ALL observations, not necessarily ones for a specific post. In that case, the second resources route that isn't nested can be very useful. This might be for doing more bulk requests, updates, etc that could apply to all posts. It provides advantages for different use cases and it's totally fine to include both of those routes/controllers for the some model (and often encouraged) so you can provide an elegant set of URLs that encapsulate the intent in the design of the url itself.


Hey Chris!

I actually have both of those routes for observations setup, but the nested resouce I'm only allowing index and show. I think accepts nested attrs makes a lot of sense here and would be very convenient to my future self. Thanks for the reply!


Ah perfect! :D

And yeah I think that'd make consuming the API a lot easier. I think the only trick then will be making sure you get all your field names right when you submit make over. There is some documentation about how that works but I can't remember where I saw it. Mostly it's just sending over an array for your observations_attributes[] and that should do the trick.

You could optionally also support the id and _destroy fields for the nested observations in case you ever wanted to be able to edit/remove observations from updating a post. That seems probably less likely to be necessary though from an API standpoint though.


Let us know how the implementation goes!


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 24,647+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.