«Лучшая» практика для спокойного POST-ответа


217

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

Я создаю новый ресурс повторно, говорю:

/books (POST)

с телом:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Я знаю, что должен вернуть 201 (Created) с заголовком Location нового ресурса:

Location: /books/12345

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

Я часто делал такой тип ответа:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Я сделал это по нескольким причинам:

  1. Я написал API для рамок переднего конца, как angularjs. В моем конкретном случае я использую угловые ресурсы, и мне часто нужен только идентификатор ресурса, чтобы найти его. Если я не вернул идентификатор в теле ответа, мне нужно было бы проанализировать его из заголовка Location.
  2. В GET всех книг я обычно возвращаю весь объект, а не только идентификатор. В этом смысле мой клиентский код не должен различать, откуда взять идентификатор (заголовок местоположения или тело).

Теперь я знаю, что я действительно нахожусь в серой зоне, но большинство людей говорят, что возвращать весь ресурс - это «плохая» практика. Но что, если сервер изменяет / добавляет информацию к ресурсу. Это определенно добавляет идентификатор, но может также добавить другие вещи, такие как отметка времени. В случае, если я не возвращаю весь ресурс, действительно ли лучше сделать POST, вернуть идентификатор, а затем заставить клиента выполнить GET для получения нового ресурса.


Я лично предпочитаю пустое тело для ответов POST. Не должно ли значение заголовка RESTful Location быть URI (уникальным идентификатором ресурса)? Поэтому, возможно, вам следует использовать его в качестве идентификатора, а не анализировать его для определения внутреннего идентификатора сервера. IMO, потребители RESTful API должны перемещаться, используя предоставленные гиперссылки, а не путь сборки, угадывая, где конкретный сервер находит ресурсы ... И, в конце концов, разве клиент уже не знает состояние только что созданного ресурса? повторение этого швы трата ресурсов сети.
ch4mp

1
Для создания / вставки, статус 201 - СОЗДАН, расположение заголовка → localhost: 8080 / сотрудников / 1 (см .: здесь )
Хасан Тарек

Ответы:


129

Возврат всего объекта при обновлении не очень уместен, но я не могу понять, почему возврат всего объекта при его создании был бы плохой практикой в ​​обычном случае использования. Это было бы полезно по крайней мере, чтобы легко получить идентификатор и получить метки времени, когда это уместно. Это на самом деле поведение по умолчанию, полученное при скаффолдинге с Rails.

Я действительно не вижу никакого преимущества в возврате только идентификатора и выполнении запроса GET после, чтобы получить данные, которые вы могли бы получить с вашим первоначальным POST.

В любом случае, пока ваш API согласован, я думаю, что вы должны выбрать шаблон, который наилучшим образом соответствует вашим потребностям. Не существует правильного способа построения REST API, imo.


26
Я знаю, что это старо, но я могу дать убедительный аргумент в пользу использования GET после вашего POST. В спецификации http / 1.1 любой исторический инструмент может игнорировать настройки кеша, переданные обратно из вашего ответа GET ... поэтому, если ваш пользователь использует кнопку назад в браузере, чтобы вернуться на эту страницу после того, как вы обновили ее с помощью POST, он может использовать устаревший кэшированные данные из оригинального GET. Так что, если вы повторно используете GET, вы можете обновить кэш и получить лучший снимок того, как выглядела страница, когда они уходили ...
Shaded

8
@Shaded Если API предназначен для использования также приложениями, ваш аргумент для выполнения двух запросов не выполняется. Там вы обычно кэшируете данные, сохраняя объекты типа модели в памяти - что обычно делается с помощью ответа на запросы POST. Что касается браузеров, то ответ на запрос POST на самом деле не помешает, пока есть конечная точка API GET.
Jeehut

Я подписываюсь на то, что Даниил заявляет здесь. Даже если вы проверяете зрелые фреймворки, такие как Spring Data, они всегда возвращают весь объект после его сохранения. Я думаю, что это хорошая практика, так как в вашем клиенте вы сохраняете сервер туда и обратно, чтобы получить ту же информацию
frandevel

205

Возврат нового объекта соответствует принципу REST «Унифицированный интерфейс - управление ресурсами посредством представлений». Полный объект - это представление нового состояния объекта, который был создан.

Вот действительно отличная справочная информация по разработке API, здесь: Лучшие практики для разработки Pragmatic RESTful API

Он включает в себя ответ на ваш вопрос здесь: Обновления и создание должны возвращать представление ресурса

Это говорит:

Чтобы предотвратить повторное использование потребителем API обновленного представления для API, попросите API вернуть обновленное (или созданное) представление как часть ответа.

Мне это кажется прагматичным, и это соответствует принципу REST, о котором я упоминал выше.


6
как насчет возврата всего набора соответствующих объектов? таким образом, возможная сортировка может быть выполнена на стороне сервера, и это облегчает реализацию
интерфейса

2
Но эти лучшие практики не являются лучшими. Автор заявляет, что HATEOAS, который важен так же, как и другие принципы, не должен использоваться, потому что «он не готов». HATEOAS никогда не будет «готов», потому что все принципы RESTful - это просто принципы архитектурного проектирования, а не конкретная реализация. Цитируемая ссылка о видении автора о RESTful API, который совсем не является RESTful из-за удаления HATEOAS. Вот почему это не лучшая ссылка :)
marcinn

1
@marcinn - вы заметите, что в первоначальном вопросе были цитаты вокруг «Best», я полагаю, потому что в этой области есть много мнений. Ссылка, на которую я указал, - это то, что я считаю практичным. Если у вас есть лучший отзыв, пожалуйста, поделитесь им. Я всегда открыт для обучения.
grahamesd

@grahamesd Реализация - это совсем не то, что принцип / шаблон архитектурного дизайна. Никто не может ожидать, что HATEOAS когда-нибудь будет готов, но есть вероятность, что кто-то создаст реализацию, приемлемую для многих. Виней также написал о сопоставлении методов http с URL-адресами и конкретными операциями (CRUD), заявил, что управление версиями с помощью префиксов URL-адресов более прагматично, написал, что фильтрация по параметрам запроса - это путь ... это хорошо, но все это мало что дает делать с RESTful архитектурой. Он писал о каком-то контракте. Это хорошо для HTTP API, но не называйте это RESTful.
Марцинн

@grahamesd Вот несколько сообщений , объясняющих это: - medium.com/@andrea.chiarelli/... - restfulapi.net
marcinn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.