3

Is it bad for a REST API to have non-unique ID for a child resource?

For example, the endpoint is:

GET /parent/:parent_name/child/:child_name

The :parent_name is unique, but a :child_name is only unique for that parent.

I decided to use names at first because the parent and child are resources that exist in external systems. This would allow the API consumers to enter the names into the URI intuitively without requiring an extra query to get an ID unique to the API like a GUID.

However, I'm starting to think this might have been a mistake. Any endpoints that use a child now need both the :parent_name and :child_name. Any endpoints where the child is the root also require the :parent_name in a query parameter, which gives me a bad feeling and I'm not sure how intuitive it is for API consumers.

Is this design with non-unique ID's for child resources acceptable, or is it better to just generate a unique ID within the API and always use that ID?

5

There are no hard rules for how to build URLs in REST, only common sense and best practices (here is for example one such guide, out of many). From a REST point of view, it's not important how the URLs look like. Something like /da39a3ee5e6b4b0d3255b is just fine as long as it identifies a resource.

In your case, the whole URL is the resource identifier at any particular point (be that of a collection of entities or just a single entity). So if you can build the URLs properly so that there are no overlaps that can potentially cause one identifier to point to more resources, then you should be fine no matter how you build the URLs and what names they contain.

With that being said, there are some problems though if you decide to use names (you don't mention exactly what those names contain so I'll assume some plain text). Like I mentioned, REST doesn't care about the URLs. We build user friendly URLs like that for users. People users. A machine doesn't care. So consider people as your target audience if you want to build URLs with names in them instead of IDs. For example, of the top of my head:

  • can people be confused when they see the same child name in different places?
  • are these names created based on some rules or free writing? If someone misspells a name, an URL is created with that name. They figure out their typo and they then fix it. Now you get another URL with the correct name that points to the same resource. How will you handle this? Rewrite rules in the server? How do you invalidate caches? etc.
  • internationalization? If people want translations you get the same name in N different languages. What happens then?
  • can people refer to the child entities and handle them like standalone entities? Basically, what you are also saying in your post, that now people need to think at one entity name and always pair it with their parent.
  • encoding? What exactly are those names? Can you mess them up between UTF-8 and ASCII for example?
  • lowercase names vs upper case names? Are they different names or the same?
  • etc.

For reasons such as these people usually prefer to stick an ID in there and call it a day. Sometimes they even use :ID-:Name (i.e. ID, dash, Name) or :ID/:Name (i.e. ID, slash, Name). The ID is used by the application while the name is there for people's convenience and is ignored by the actual execution/routing engine of the application. See as an example this actual post and compare these two URLs:

Designing a REST API resource with a non-unique ID, but unique composite ID

Designing a REST API resource with a non-unique ID, but unique composite ID

The application looks at the ID of the post, what's after it is for people and SEO.

To conclude, there is no definitive answer to this question. Like I said, just common sense and best practices. So use common sense and read on some best practices. My personal answer to this would be to try to avoid names because of the issues I mentioned above. You can make a mess of thing with names, but less so with (usually numerical) IDs. And your API will be more easy to evolve with IDs instead of names.

| improve this answer | |
  • Thank you for the detailed answer! It felt like it was getting slightly awkward to code around, but I see there were more potential issues as well. – peefartpoop Mar 22 at 0:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.