/users?role=admin, where admin is probably some kind of slug
/users?role=2, where 2 refers to our internal roles dictionary table primary key.
Which of the two is prefered?
/users?role=admin, where admin is probably some kind of slug vs /users?role=2, where 2 refers to our internal roles dictionary table primary key.
Which of the two is preferred?
Which of the two is more likely to work when you change the implementation on the server?
URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer.
Part of the point of REST is that the client and server are communicating via messages. The resources on the server act as an adapter, or anti-corruption layer, transforming the messages into something that the domain model understands.
Cool URI don't change; they are coupled to the semantics of the message rather than the implementation.
Named values are more debuggable, which is a big benefit.
If the role name may be user-provided and is not limited to a few presets, then two issues have to be considered:
The name may include security sensitive data. That is problematic if the URL were to be visible in other contexts. Depending on the errors you return, this could also be used to check for the existence of a specific role.
The names might not be unique. Either the names are scoped so that the same name can refer to different roles in different scopes, or you need a numeric ID.
If all roles are built-in but use IDs instead of mnemonic names, then the question arises how clients know which ID they have to use.
If the API is purely internal (and the API clients can be changed together with the API) then this is less important, but using the correct role ID is still a possible source of errors.
TLDR: It doesn't matter.
If your API is public then you'll have to provide documentation matching the IDs to the names. If your API is private then, as someone else said, you'll have the ability to change the client code as you please so changes to the API won't break stuff.
I'd personally go with the IDs because of query string limitations, bandwidth efficiency (minuscule) and lack of need to match the name to the ID on the server.
The debugging benefits that someone else mentioned are easily obtained by having your error handlers explaining what's wrong while running in debug mode.