What matters here that you need to be able to identify your resources. The simplest approach is:
/api/posts/{postId}
/api/organizations/{organizationID}
/api/groups/{groupID}
/api/users/{userID}
As of the admin vs regular user, it is called role-based access control (RBAC). So roles can be another resource, though if you never want to edit them, then just hardcode them and manage roles by users and groups.
The path is for the hierarchical part of resource identification the query is for non-hierarchical part, but they sort of overlap, which is not a big deal, you can even support both. So the URI is a unique identifier, but it is not exlusive, you can have multiple URIs, which identify the same resource.
As of the query part, I like to use it for filtering collections and return always an array even if it contains one or zero items. So with my approach:
/api/users/{userID}
/api/users/?id={userID}
These two are not exactly the same, because the second one returns an array with a single item. But this is not a standard, just my preferred approach.
I like the upper simple URIs instead of the heavily nested ones and add more depth only if it grows really big. It is like namespacing in a programming language. For a while you are ok with the global namespace, but if it grows big, then you split it up into multiple namespaces.
In your case I think I would do it the opposite direction as you did:
- Get all posts by organization:
/posts/?organizationId={id}
- Get all posts by group:
/posts/?groupId={id}
- Get all posts by user:
/posts/userId={id}
Another approach is:
- Get all posts by organization:
/organizations/{id}/posts/
- Get all posts by group:
/groups/{id}/posts
- Get all posts by user:
/users/{id}/posts
You can even support both approaches simultaneously or a different approach you like better.
Tbh. when you do something that is really REST, then the URI structure does not matter this much from REST client perspective, because it checks the description of the hyperlink it gots from the server and does not care much about the URI structure. So the response should contain something like the following:
{
"type":"link",
"operation":"listPostsForOrganization",
"method": "get",
"uri": "/api/organizations/123/posts/",
}
And you use the API with the client like this:
let organization = await api.getOrganizationForUser(session.currentUser)
let posts = await api.listPostsForOrganization(organization)