4 ms·
Another two reasons to avoid nested resources, are performance and coupling. A nested resource is hard to optimize. Simple, atomic, flat resources can be cache
by berkes 5y ago
Another two reasons to avoid nested resources, are performance and coupling.
A nested resource is hard to optimize. Simple, atomic, flat resources can be cached (by clients, proxies or server) much more efficient. Once you allow nested resources, there's no going back, as clients will depend on them. So you've effectively disabled lots of performance improvement options.
A nested resource implies data relations. Tightly coupled to a data model. One that will change over time, yet the api is hard to change. If you have a Project nested in your Users, and the business now needs multiple projects per user, this is hard to change with nested resources, but much easier with endpoints, the /users/:id/project can be kept and return e.g. the first project, next to a new /users/:id/projects.
- berkes 5y agoAnd a third one is more architectural in nature. Your domain has bounded context (even if you haven't defined these explicitely). Within those bounded contexts, you'll have atomicity-constraints: transaction boundaries. Those should typically align, but are hard to find in a new project and will grow and shift over time. To take that User/Project example: the Project and User have different transaction boundaries: it matters not that a User.username is updated while a Project.projectname is updated differently. But it does matter when a username and password get updated simultanous. And -for the sake of the xample- it matters that the user + users-roles must be within one transaction boundary. By allowing nested resources on mutations you essentially break the bounded contexts and the transaction boundaries. By not allowing nested resources on mutations, but allowing them on-read, you introduce inconsistencies: the resources on-insert differ from the resources on-read. This becomes even more problematic when you do allow certain nested resources on mutations but not on others (because, behind the scenes you've determined a bounded context/transaction boundary). To an API consumer this is entirely arbitrary. Why can I "PUT user.roles[1]" but not "PUT user.projects[1]", yet have both included at wish on-read? With nested resources, here too, you paint yourself in corners. They take away a lot of choices you likely want to make in future. Being a bit more restraining in what you allow clients to do, keeps those options open for you. In this case, keeps the option to move transaction boundaries when business needs require (and they will).