REST API Design – Managing Resource Ownership

api-designrestweb-api

Let's say there are Users and Pets. Each Pet has a single User as its owner, and a globally unique id. Endpoints could be

/users/1/pets/2

/pets/2

I feel like the first option could be unintuitive since IDs are inconsistent within one User. Which one should I use?

Best Answer

You have stated your choice that pets have a globally unique id. This means that a pet can be transferred to another owner without changing the pet's id (generally a good thing for stability under db refactoring). Further, it means that should you want to, you can have two owners (e.g. a couple or roommates, etc..) for the pet. (Not to mention directly referencing a pet as you note.)

Therefore, I'd say use the /pets/<id>.

However, you can still list pets for one user with /users/1/pets, and user for pet with /pets/<id>/user (if limited to one or /pets/<id>/users for more), for one, because we're talking about the API here not your normalized database hidden behind it. The use of simple integers for ID's may be confusing (so you could use something else), but when people see that /pets is an endpoint, I think they'll get it.

Have a look a OData, if you haven't seen it already. A good way to layer on top of REST, and provide for filters, nested data, even doing joins, from an API perspective. For example, https://stackoverflow.com/q/3920758/471129 gives a good discussion about using navigational properties for specific joins without having to introduce foreign keys.

Also, I think you will eventually want to remove the limitation of one owner per pet, as this is not going to stand the test of time. Cars, houses, bank accounts, all have notions of multiple owners. Children can have multiple guardians, why not pets having multiple owners.

Related Topic