Getting a resource using another resource's id

2019-05-30 07:20发布

问题:

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?

回答1:

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.



回答2:

I'd just add a query paramter

GET /users?username=john


回答3:

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)



标签: rest