REST API DESIGN - получение ресурса через REST с разными параметрами, но с тем же шаблоном URL
У меня есть вопрос, связанный с дизайном URL REST. Я нашел здесь несколько релевантных сообщений: Различные представления RESTful одного и того же ресурса и здесь: URL-адрес RESTful для предоставления ресурсов различными полями, но ответы не совсем ясны в отношении того, что такое лучшие практики и почему. Вот пример.
У меня есть URL REST для представления ресурса "users". Я могу ПОЛУЧИТЬ пользователя с идентификатором или с адресом электронной почты, но представление URL-адреса остается неизменным для обоих. Просматривая много блогов и книг, я вижу, что люди делали это по-разному. Например
прочитайте эту практику в книге и где-нибудь в stackoverflow (я не могу найти ссылку снова)
GET /users/id={id}
GET /users/email={email}
прочитайте эту практику во многих блогах
GET /users/{id}
GET /users/email/{email}
Параметры запроса обычно используются для фильтрации результатов ресурсов, представленных URL-адресом, но я также видел, что эта практика также используется
GET /users?id={id}
GET /users?email={email}
Мой вопрос заключается в том, что из всех этих практик, которые будут иметь смысл для разработчиков, потребляющих apis и почему? Я считаю, что нет никаких правил, установленных в камне, когда речь заходит о проектах REST url и соглашениях об именах, но я просто хотел узнать, какой маршрут я должен предпринять, чтобы помочь разработчикам лучше понять apis.
Вся помощь оценена!
Ответы
Ответ 1
По моему опыту, GET /users/{id} GET /users/email/{email}
- наиболее распространенный подход. Я также ожидал, что методы возвратят 404 Not Found, если пользователь не существует с предоставленными id
или email
. Я бы не удивился, увидев GET /users/id/{id}
, (хотя, на мой взгляд, он лишний).
Комментарии к другим подходам
-
GET /users/id={id} GET /users/email={email}
- Я не думаю, что видел это, и если бы я это увидел, это было бы очень запутанно. Это почти похоже на попытку имитировать параметры запроса с параметрами пути.
-
GET /users?id={id} GET /users?email={email}
- Думаю, вы ударили ноготь по голове, когда вы упомянули параметры запроса для фильтрации.
- Было бы целесообразно называть этот ресурс как с помощью
id
, так и email
(например, GET /users?id={id}&email={email}
)? Если нет, я бы не использовал один ресурсный метод, подобный этому.
- Я ожидал бы этот метод для получения списка пользователей с необязательными параметрами запроса для фильтрации, но я бы не ожидал, что
id
, email
или любой уникальный идентификатор будут среди параметров. Например: GET /users?status=BANNED
может вернуть список запрещенных пользователей.
Отметьте этот ответ из соответствующего вопроса.
Ответ 2
Посмотрев на это прагматично, у вас есть коллекция пользователей:
/users # this returns many
Каждый пользователь имеет выделенное место ресурса:
/users/{id} # this returns one
У вас также есть несколько способов поиска пользователей:
/users?email={email}
/users?name=*bob*
Так как это все параметры запроса для /users, все они должны возвращать списки.. даже если это список из 1.
Я написал сообщение в блоге о прагматичном дизайне RESTful API, в котором говорится об этом, среди прочего, здесь: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Ответ 3
Об пользовательских ресурсах
на пути /users
вы всегда получите возвращаемый ресурс коллекции.
на пути /users/[user_id]
вы получите ресурс singleton, представляющий пользователя с идентификатором [user_id] или ответ 404, если у пользователя нет запрошенного [user_id] (или запрещенного (401), если вам не разрешено доступ к ресурсу и т.д.).
Каждый путь ресурса имеет только один идентификатор, и вы используете его для поиска/идентификации ресурсов. Невозможно использовать несколько идентификаторов для одного и того же ресурса на одном пути ресурса. Если вы получите ресурс, возвращенный в ответе, этот идентификатор включен в ответ как собственный HREF для поиска/идентификации ресурса.
Вы можете запросить путь /users
с параметрами GET
/query. Это вернет коллекцию пользователям, отвечающим запрошенным критериям. Возвращаемая коллекция содержит все пользовательские ресурсы с их локализацией/идентификацией self HREF.
О ресурсах электронной почты
Если я посмотрю, что вы предложили по электронной почте, я бы предпочел следующее:
Письма от пользователей также являются ресурсами. Поэтому я думаю, что /users/[user_id]/emails
возвращает коллекцию адресов электронной почты для пользователя с id user_id
. /users/[user_id]/emails/[email_id]
возвращает электронное письмо пользователя с user_id и ['email_id']. То, что вы используете как идентификатор, зависит от вас, но я бы придерживался целого числа. Вы можете удалить электронное письмо от пользователя, отправив запрос DELETE
на путь, который идентифицирует электронное письмо, которое вы хотите удалить.
Например, DELETE
на /users/[user_id]/emails/[email_id]
удалит письмо с адресом электронной почты, которое принадлежит пользователю с user_id. Скорее всего, только этот пользователь может выполнить эту операцию удаления. Другие пользователи получат ответ 401.
Если у пользователя может быть только один адрес электронной почты, вы можете придерживаться /users/[user_id]/email
Это возвращает ресурс singleton. Пользователь может обновить свой адрес электронной почты PUT
ting или POST
с новым адресом электронной почты по этому URL-адресу. Если в вашем приложении вы не разрешаете пользователям без электронной почты, вы должны ответить 401, если он отправит запрос DELETE
на этот URL-адрес.