it-swarm.com.ru

REST API DESIGN - получение ресурса через REST с другими параметрами, но с одинаковым шаблоном URL

У меня есть вопрос, связанный с дизайном REST url. Я нашел несколько соответствующих постов здесь: Различные представления RESTful одного и того же ресурса и здесь: Ссылка RESTful на ресурс GET по разным полям но ответы не совсем ясны о том, что лучше практики есть и почему. Вот пример.

У меня есть REST URL для представления ресурса "пользователи". Я могу получить пользователя с идентификатором или с адресом электронной почты, но представление 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}

Мой вопрос, из всех этих методов, какой из них наиболее целесообразен для разработчиков, использующих API, и почему? Я считаю, что нет никаких правил, установленных в камне, когда речь идет о REST проектах URL и соглашениях об именах, но я просто хотел узнать, какой путь мне следует выбрать, чтобы помочь разработчикам лучше понять API.

Вся помощь приветствуется!

61
shahshi15

По моему опыту, GET /users/{id} GET /users/email/{email} является наиболее распространенным подходом. Я также ожидал бы, что методы вернут 404 Not Found, если пользователь не существует с предоставленным id или email. Я также не удивлюсь, увидев GET /users/id/{id} (хотя, на мой взгляд, это избыточно).

Комментарии к другим подходам

  1. GET /users/id={id} GET /users/email={email}
    • Я не думаю, что видел это, и если бы я видел это, это было бы очень запутанным. Это почти как попытка имитировать параметры запроса с параметрами пути.
  2. GET /users?id={id} GET /users?email={email}
    • Я думаю, что вы ударили по голове, когда упомянули об использовании параметров запроса для фильтрации.
    • Имеет ли смысл когда-либо называть этот ресурс с id и email (например, GET /users?id={id}&email={email})? Если нет, я бы не использовал один метод ресурсов, как это.
    • Я ожидал бы, что этот метод для извлечения списка пользователей с необязательными параметрами запроса для фильтрации, но я бы не ожидал, что id, email или любой уникальный идентификатор будет среди параметров. Например: GET /users?status=BANNED может вернуть список заблокированных пользователей.

Проверьте этот ответ из соответствующего вопроса.

80
DannyMo

Глядя на это прагматично, у вас есть коллекция пользователей:

/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

32
Vinay Sahni

О пользовательских ресурсах

по пути /users вы всегда получите возвращенный ресурс коллекции.

по пути /users/[user_id] вы получите одноэлементный ресурс, представляющий пользователя с его идентификатором [user_id] или, альтернативно, ответ 404, если нет пользователя с запрошенным [user_id] (или запрещено (401), если вам не разрешен доступ к запрошенному пользователю ресурс и т. д.). Каждый путь к ресурсу имеет только один идентификатор, и вы используете его для поиска/идентификации ресурсов. Невозможно использовать несколько идентификаторов для одного и того же ресурса на одном и том же пути к ресурсу. Если вы получаете ресурс, возвращенный в ответе, этот идентификатор включается в ответ в виде собственной HREF для определения местоположения/идентификации ресурса.

Вы можете запросить путь /users с помощью GET/параметров запроса. Это вернет коллекцию с пользователями, которые отвечают запрошенным критериям. Возвращаемая коллекция содержит пользовательские ресурсы, все с идентифицирующим себя HREF.

О ресурсах электронной почты

Если я посмотрю на то, что вы предложили для электронной почты, я бы предпочел следующее:

Письма от пользователей также являются ресурсами. Поэтому я думаю, что /users/[user_id]/emails возвращает коллекцию адресов электронной почты для пользователя с идентификатором user_id. /users/[user_id]/emails/[email_id] возвращает электронное письмо пользователя с user_id и ['email_id']. То, что вы используете в качестве идентификатора, зависит от вас, но я бы придерживался целого числа. Вы можете удалить электронное письмо от пользователя, отправив запрос DELETE по пути, который идентифицирует электронное письмо, которое вы хотите удалить. Так, например, DELETE в /users/[user_id]/emails/[email_id] удалит письмо с email_id, которое принадлежит пользователю с user_id. Скорее всего, только этот пользователь может выполнять эту операцию удаления. Другие пользователи получат 401 ответ.

Если у пользователя может быть только один адрес электронной почты, вы можете придерживаться /users/[user_id]/email. Это возвращает одноэлементный ресурс. Пользователь может обновить свой адрес электронной почты с помощью PUTting или POSTing нового адреса электронной почты по этому адресу. Если в вашем приложении вы не разрешаете пользователям без электронной почты, вы должны ответить 401, если он отправляет запрос DELETE на этот URL.

2
Wilt