0

It's common to nest resources in a RESTful API. For example, to retrieve the employees in company having ID=5:

GET /companies/5/employees

Is it also generally acceptable in a REST design to put resources in a common "directory" where they don't really belong-to a common parent resource instance? This is more of a "is-a" relationship, where I think the typical nested structure has the nested resources in a "belongs-to" relationship.

For example, is it acceptable to group two different resources (internal agents, external agents) like follows? In this case the agents part of the path is a category that describes its descendants but isn't really a parent resource.

GET /agents/internal
GET /agents/external

There are no plans to add any resources using the /agents path; it is solely for grouping purposes.

Or is that to be avoided for something like this?

GET /internal-agents
GET /external-agents

I feel like the second option is more correct, but there is an aesthetic to the first option that that I like.

william
  • 459
  • 7
  • 18
  • Possible duplicate of [What are best practices for REST nested resources](http://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources) – lorefnon Dec 03 '15 at 20:21
  • @lorefnon I saw that question but do not think it is similar. I'm not asking if I should have multiple URLs for the same resource (top level vs nested inside its parent) or which of the two is preferable. My question is whether it's acceptable to nest children of "is-a" relationships where they do not belong to a common parent resource. – william Dec 03 '15 at 20:25

1 Answers1

1

Given that you have some agents which can be internal or external:

  • /agents/internal is a terrible idea breaking URL consistency
  • /internal-agents is a valid idea but beware of drawbacks
  • A filter could be better for this use case: GET /agents?status=internal

/agents/internal is a terrible idea breaking URL consistency

Having /agents/internal is a terrible idea, it MUST not be used as it will lead to inconsistent URLs in your API which will not be easily understand by humans but also programs.

  • The best pattern for REST URL (exluding domain and versioning matters) is this one: /resources/{resouce id}/sub-resources/{sub-resource id}// No more than 2 levels should be allowed. Your first example /companies/5/employees is a perfect good example.
  • Adding a /agents/internal URL will make your API's URLs inconsistent and difficult to understand for humans but also programs. You can end having GET /agents/2 which return agent with id 2 and also GET /agents/internal which return a list of internal agents. Same URL structure but different meanings.

Using a consistent structure for URL helps to understand the semantic without even knowing what an API does.

/internal-agents is a valid idea but beware of drawbacks

Your idea of having two specific resources internal-agents and external-agents is valid. But it can have some drawbacks depending on the exact use case:

  • if you add more status, like partner for example, you'll have to add a new resource partner-agents
  • if a consumer want to retrieve both type it'll have to make to calls or you'll have to create a /agents resource

A filter could be better for this use case: GET /agents?status=internal

A third idea would be to consider internal and external as filter on some status on /agents resource.

  • GET /agents returns all agents (internal + external)
  • GET /agents/2 returns agent with id 2
  • GET /agents?status=internal returns agents with internal status
  • GET /agents?status=external returns agents with external status

And if you add a new status like partner:

  • GET /agents returns all agents (internal + external + new partner status)
  • GET /agents/2 still returns agent with id 2
  • GET /agents?status=internal still returns agents with internal status
  • GET /agents?status=external still returns agents with external status
  • GET /agents?status=partner returns agents with new partner status
  • GET /agents?status=internal,partner returns agents with internal or partner status

Choosing between filter and specific resources is only a metter of context. The only thing to keep in mind is to ensure URLs consistency.

Arnaud Lauret
  • 4,961
  • 1
  • 22
  • 28