Подтвердить что ты не робот

Должен ли ответ RESTful GET возвращать идентификатор ресурса?

Ряд разработчиков здесь имеют дружескую (кто-то скажет религиозную) дискуссию о том, должен ли запрос GET из RESTful API вернуть идентификатор запрашиваемого ресурс. Пусть предполагается следующий запрос GET:

http://my.api.com/rest/users/23

В настоящее время возвращается:

{"name": "Jim", "age": 40, "favoriteColor": "blue"}

Обратите внимание, что в наборе результатов отсутствует идентификатор "id".

В этой проблеме есть 4 лагеря.

CAMP # 1: Когда вызывающие абоненты делают запрос GET, они уже знают ID. Поэтому в результирующем наборе должно быть не идентификатор. Если вызывающим абонентам нужны эти данные, чтобы разрешить редактирование пользовательского интерфейса, то вызывающим абонентам необходимо пройти через идентификатор 23, возможно, добавив элемент { "id": 23} в JSON вручную.
Люди в лагере # 1 также утверждают, что наличие идентификатора в результирующем наборе указывает на то, что это значение может быть изменено, что, конечно, не может.

CAMP # 2: Без идентификатора набор результатов JSON не может использоваться изначально для операций редактирования/обновления в формах пользовательского интерфейса. Вместо этого механизм обратного вызова AJAX должен отвечать за прохождение вокруг полей ИД и вручную добавление их в результирующий набор. Это похоже на klunky и склонность к ошибкам. Парни пользовательского интерфейса делают аргумент, что результирующий набор "чувствует", как будто он пропускает данные, которые должны присутствовать, а именно идентификатор.

CAMP # 3: Эти люди обеспокоены согласованностью. Если у нас когда-либо есть коллекция пользовательских объектов, возвращаемых API, эти объекты ДОЛЖНЫ включать идентификатор. Поэтому для согласованности одноэлементная версия GET также должна включать идентификатор.

CAMP # 4:. Эти люди предполагают, что запрос GET для пользователя может возвращать метаданные в форме HyperMedia или SelfLinks, которые будут включать идентификатор.

Это не эзотерический "Кто прав?" аргумент. Подход, который мы принимаем, будет определять форму нашего API и повлиять на рабочие нагрузки нескольких разработчиков за последние несколько недель.

4b9b3361

Ответ 1

Это вопрос мнения, который не является тем Вопросом, который Stackoverflow любит видеть. в любом случае, я предложу свою.

Вы возвращаете представление состояния объекта или ресурса. Идентификатор является частью этого представления и поэтому должен быть включен в пакет JSON. Это свойство ресурса. Независимо от того, знает ли вызывающий абонент ID или нет, это не особенно актуально для обсуждения. ЛАГЕРЬ № 1 находится на шаткой почве.

То, что вы поднимаете о коллекциях, очень актуально. Имеет ли смысл использовать одно представление для операции retrieve-1 и другое представление для операции retrieve-N? Думаю, нет.

Однако проблема, с которой вы сталкиваетесь, более общая - какие данные следует включать в представление, которое передается клиентам, и при каких обстоятельствах? В некоторых случаях вызывающий объект просто не заботится о значительном подмножестве свойств. Особенно в сценариях, где извлекается большой набор объектов - где стоимость передачи данных больше по сравнению с базовыми расходами на связь - вы хотели бы оптимизировать то, что отправлено обратно.

Все достаточно зрелые протоколы REST имеют возможность формировать возвращаемые данные.

Примеры см. в

  • API-интерфейс Facebook, http://developers.facebook.com/docs/reference/api/
  • StackExchange API v2.0 - есть "фильтр", который вы можете передать, чтобы точно сформировать то, что возвращается.
  • API CouchDb - имеет функцию отображения для каждого представления, которая определяет, какие данные возвращаются. Он также имеет пустой параметр запроса, include_docs, который направляет сервер на включение полных объектов или только метаданных. (В некоторых случаях вам может потребоваться только подсчет данных, а не фактические данные.)

Facebook позволяет явно указывать нужные поля.

enter image description here

API-интерфейс stackexchange интересен. Они определили совершенно новый тип объекта для поддержки формирования. Вы можете использовать API для определения "фильтра" и сохранения его на стороне сервера. Затем в вашем запросе вы передаете параметр фильтра с идентификатором фильтра, а возвращаемые представления объектов включают все атрибуты, указанные в фильтре. Без фильтра вы получаете "по умолчанию" подмножество полей. Чтобы получить "все поля", вам нужно определить фильтр "все включено".

вы можете увидеть это в действии на https://api.stackexchange.com/docs/answers

... и особенно см. диалоговое окно спецификации фильтра.

enter image description here


Нет единого правильного способа сделать что-то. Вам нужно сбалансировать сложность функции "форматирования", которую вы поддерживаете, с затратами на разработку и потребностями приложений, которые будут использовать API.

Ответ 2

Старый вопрос, но так как я здесь что-то искал, вот еще одно мнение:

Прежде всего, я думаю, что URL-адрес должен быть:

http://my.api.com/rest/Users/23

не

http://my.api.com/rest/getUsers/23

"GET" лежит на методе HTTP, а не на URL-адресе. Это просто имя, но помогает сделать вещи яснее, ИМХО.

Если вы думаете об этом, модификация ресурса должна произойти в том же URL-адресе с помощью PUT

PUT http://my.api.com/rest/Users/23

В этом случае клиенту необходимо отслеживать URL-адреса, а не идентификаторы. Не имеет значения, возвращает ли ресурс поле идентификатора. Клиент должен сохранить карту того, откуда он был получен.

Если вы попытаетесь перенаправить ресорцию на другой URL-адрес, скажите " http://my.api.com/rest/Users/24", произойдет несколько сценариев:

1) http://my.api.com/rest/Users/24 уже существует на сервере, а сервер принимает ресурс как обновление

2) http://my.api.com/rest/Users/24 не существует на сервере и:

a) сервер соглашается с тем, что Пользователь предоставляет идентификатор (24) для неиспользуемого ресурса (не рекомендуется) б) сервер принимает PUT как POST

В a + b сервер создаст новый ресурс.

Итак:

1) В зависимости от того, насколько вы доверяете своему клиенту, вы, вероятно, должны создать на сервере контроль "check-in/check-out", чтобы избежать перезаписи одного ресурса другим (это RESTful?)

2) Вы не должны принимать клиентов, создающих идентификаторы (ОК, чтобы отправить http://my.api.com/rest/Users/, а не http://my.api.com/rest/Users/24), и вы не должны принимать PUT для несуществующих ресурсов.

ИЗМЕНИТЬ

Итак, я считаю, что ресурс идентифицируется по его URL-адресу, а не по ID. Или, другими словами, идентификатор ресурса http://my.api.com/rest/Users/23, а не 23.

Имеет смысл?