I have an API that manages projects. You can get a single project via this endpoint, where {id} is a numeric project ID:


Each project can have one or more tags. Now I want to add an endpoint that will return an array of all tags that are assigned to at least one project.

My inclination is to put this endpoint at:


But I have a vague feeling that that may not be the best way to do it, because now the /projects/{id|"tags"} route has two different meanings.

Would it be better to add a distinct /project_tags endpoint instead? Are there pros/cons, or established practices in this regard?

  • But I have a vague feeling that that may not be the best way to do it, because now the /projects/{id|"tags"} route has two different meanings. URIs are addressed to HTTP clients, who could not care less about meanings. If you are writing URIs for humans, then you have many more problems. More precisely one for every single human being allowed to read your API endpoints.
    – Laiv
    Commented Oct 15, 2020 at 11:48

3 Answers 3


If a tag is a distinct entity in your domain then I would do this:


Otherwise I might just do this:


Overloading REST API operations only leads to late nights and stress.


REST doesn't care what spelling conventions you use for your resource identifiers


Those are both fine. The machines don't care.


  1. the routing framework you are using may not be able to support what you want, meaning that you will have to write some extra code yourself to resolve the "ambiguity"
  2. human beings reading the identifiers may get confused?

There's no great advantage to this arrangement, though -- unless you are finding that using relative references to link the two resources is unusually important in your circumstances.

So it is probably wiser to choose a different path for your tags resource


I have been in that situation working with node+express, and while you can make both pattern works, the /projects/{id|"tags"} got me into messy a bit of a messy code base, because I wanted to have a middleware running after my controler and ended up having both route being taken.

I ended up haveing something like:


So I could avoid routing bug

In the end it depends on your framework router and how you organise your code. Another way I could have solved this is to just end() my request in my controler and declaring the tags route before the id one so it hit first, but other framework may have different internal behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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