0

Normally I expose endpoints in this way:

/api/1/users
/api/1/users/{uid}
/api/1/groups
/api/1/groups/{gid}
/api/1/items
/api/1/items/{iid}

To represent hierarchy I usually go this way:

/api/1/groups/{gid}/users
/api/1/users/{uid}/items

Or to get similar results:

/api/1/users?group_id={gid}
/api/1/items?user_id={uid}

Everything goes well unless you face this:

/api/1/users
/api/1/groups   # groups of users
/api/1/items
/api/1/groups   # groups of items

Here I could imagine 2 options:

  1. To change the endpoint name:

    /api/1/users
    /api/1/groups
    /api/1/items
    /api/1/item_groups
    
  2. To modify path by adding some prefix or namespace or scope:

    /api/1/{users_prefix}/users
    /api/1/{users_prefix}/groups
    /api/1/{items_prefix}/items
    /api/1/{items_prefix}/groups
    

I prefer prefixes because they make item relations a bit more visible.
On the other hand such conflicts are quite rare and prefixes make path more complex.

Also I have doubts because /api/1/{items_prefix} doesn't represent any resource or collection.
Though /api also doesn't and it is common practice to start path with /api/{version}.

So I can't figure out what is the best approach for resolving name conflicts from perspective of REST principles or best practices?

Thanks in advance.

Lee Mon
  • 1
  • 1

1 Answers1

1

Usual disclaiminer: REST does not care about your url structure, and there are no standard principles here. What follows is more or less a suggestion/opinion:

My understanding from your question is this:

  1. There are 3 main concepts, items, users and groups.
  2. You want to be able to get lists of all items, all groups, all users
  3. You want to be able to see items per group and items per user.

Based on this I would probably opt for a structure like:

# users

/user           - list of users
/user/{id}      - one user
/user/{id}/item - items belonging to 1 user

# groups

/group           - list of groups
/group/{id}      - one group
/group/{id}/item - items belonging to 1 group
/group/{id}/user - users belonging to one group

# items

/item       - list of all items. If this is meaningless, just throw a
              useful error that tells the developer why there is no root
              collection for this.
/item/{id}  - one item
Evert
  • 93,428
  • 18
  • 118
  • 189
  • Thanks for your response. I got the idea about no rules for url structure. Regarding your proposal - there we have mixed two different entities - user groups and item groups. These are quite different things. Imagine to have in one list 'Administrator' and 'Food'. In addition we have double meaning for retrieving [] for GET /group/{id}/item. It could be request of valid item group without items in it or it could be request to user group and we have no chance to distinguish them. – Lee Mon Jun 20 '20 at 08:35
  • If you have 2 distinct entities and you're worried about confusion, call them `usergroup` and `itemgroup`. – Evert Jun 20 '20 at 20:50
  • Well, this is one of the two variants I've described in question: 1. /api/1/user_groups 2. /api/1/{user_prefix}/groups What about reasoning to choose one instead of another? Question is about reasoning. ) – Lee Mon Jun 21 '20 at 07:22