I am defining a REST API and am not sure about naming an endpoint.
I have the following method already
GET /users/{user_id}
This returns the following:
{
"user_id": "some id",
"username": "some username (1:1 with user_id)",
...
}
I want an endpoint to retrieve the resource by username
, and I am not sure if it should be
GET /users/username/{username}
or rather
GET /usernames/{username}/user
or something else?
Usually a resource is uniquely identified by one single identifier. In your case that would be the user_id
. So your GET /users/{user_id}
RESTful route makes perfect sense if the user_id
is what uniquely identifies a user in your system.
On the other hand if you want to be searching users by some other criteria (like a username
) you could just use query string parameters:
GET /users?username=foo_bar
which will obviously return an array of users whose username matches this criteria and if in your case the username is unique this array will always contain at most one element:
[
{
"user_id": 123,
"username": "foo_bar"
}
]
On the other hand if you decide that user_id
is some internal system identifier for the user
resource in your system (for example that could be the primary key in your SQL database) and you want to expose some friendlier unique id in your RESTful facade to the users, then you might consider using GET /users/{username}
. Of course in this case you should very well define what a username
is and what are the allowed characters for it because things could quickly turn into a nightmare if you allow some special characters in a username. Here's a good read
on this topic that I very strongly encourage you to go through and very well understand what are the allowed characters in the path segment of an URL.
I'd just add a query paramter
GET /users?username=john
Retrieving users by username does not really fit in the REST scheme, so I would either go with the already proposed solution /users?name=....
or [possibly more comprehensive] /users/<username>
. I would use the latter only if the usernames do not need to be URI-encoded (in the best case - do not contain chars other than alpha-numeric and underscore)