0

Suppose my system has Organizations which contain Departments which contain Work Areas, so it makes sense for me to query something like get /organization/o1/department/d2/workarea/w3/employees to get a list of employees in Work Area W3 that's part of Department D2 that's part of Organization O1.

Let's further suppose that those numbering spaces are guaranteed separate and each item is unique, such that there is definitely no other Work Area W3 anywhere. The only Work Area W3 is clearly and uniquely part of Department D2. And so on up the hierarchy.

Two questions:

  • Is it good design to support a REST URL like /organization/o1/department/d2/workarea/w3/employees (because it fully represents the resource) or is it better support something more like /workarea/w3/employees (because it's guaranteed unique and the server knows what it's looking for)?
  • In implementation, is it good design to support the "long" resource path but also make everything but the last element optional? E.g., /[organization/o1/][department/d2/]workarea/w3/employees with the optional bits in square brackets?

Curious about what is best practice, and why.

1
  • If it were up to me, I would assign work areas a unique ID (for example, 100250) and get the employees using /workarea/100250/employees. W3 sounds like a descriptive code that I might want to change in the future. And furthermore, I would keep the hierarchy out of the endpoints specific to work areas. If I want the hierarchy then I can get a list of organizations or departments, but if I only want work area employees then I don't want to have to craft a URL with organization and department.
    – Dan Wilson
    Oct 25, 2021 at 3:21

2 Answers 2

1

Under a strict interpretation of REST, the format of URLs has no meaning whatsoever. REST as originally proposed says that resources are "discovered" using "hypermedia" - that is, you request one resource, and it gives you links to others. Proponents of this idea sometimes suggest deliberately making your URLs not meaningful (e.g. all indistinguishable UUIDs) so that API users don't "cheat" by guessing URLs.

If you're not trying to go down that route, and do want users to guess your URLs, then the question becomes how they're expected to guess them:

  • If there's a possibility that a client will know it wants "Work Area W3", but doesn't know the organization and department for that work area, asking them to include the extra segments in the URL leads to something of a Catch-22.
  • On the other hand, if the client is not expected to know that "Work Area W3" is a globally unique name, and should always be looking up the Organisation and Department first, the longer URL might be appropriate.
1
  • This is very helpful, thank you. I was oversimplifying my problem space to make this question make sense to this audience, and in fact the consumers of this service will know about the global uniqueness. So I think I'll go with the /workarea/w3 solution.
    – catfood
    Oct 26, 2021 at 2:23
2

Is it good design to support a REST URL like /organization/o1/department/d2/workarea/w3/employees (because it fully represents the resource) or is it better support something more like /workarea/w3/employees (because it's guaranteed unique and the server knows what it's looking for)?

Those spellings are both fine.

The first spelling allows you to take advantage of dot segments and relative resources to identify another resource within the same path segment hierarchy (ex: ../w7/employees). The second spelling has the advantage of being succinct, and might be better when viewed in a browser history, or in an HTTP log, or when documenting....


In implementation, is it good design to support the "long" resource path but also make everything but the last element optional? E.g., /[organization/o1/][department/d2/]workarea/w3/employees with the optional bits in square brackets?

Maybe? Remember: to the world outside of your implementation

/organization/o1/department/d2/workarea/w3/employees
/workarea/w3/employees

these are two different resources, and will be treated that way. When requests target these resources, the responses will be cached differently, and invalidating the responses for one will leave stale copies of the other.

That doesn't mean that it's the wrong choice to make, just that supporting both has consequences. In some cases, you might instead have one resource redirect to the other, or have them share a representation using the Content-Location header. There are different trade offs you might make depending on context.

But me: if I didn't have a compelling requirement for two resources, I would try to get by with just one.

1
  • This is very helpful, thank you. Good point about the Content-Location header and also about caching. I think I'll go ahead with the simpler shorter URI scheme.
    – catfood
    Oct 26, 2021 at 2:24

Your Answer

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

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