Создайте запрос с сообщением, которое кодирует ответ 200 или 201 и содержание


предположим, я пишу службу REST, целью которой является добавление нового элемента данных в систему.

Я планирую опубликовать в

http://myhost/serviceX/someResources

предположим, что это работает, какой код ответа я должен использовать? И какое содержание я могу вернуть.

Я смотрю на определения кодов ответа HTTP и см. эти возможности:

200: Return сущность, описывающая или содержащая результат действия;

201: какие значит создал. Значение * запрос был выполнен и привел к созданию нового ресурса. На вновь созданный ресурс может ссылаться URI(Ы), возвращаемый в сущности ответа, с наиболее конкретным URI для ресурса, заданного полем заголовка местоположения. Ответ должен включать в себя объект, содержащий список характеристик ресурса и местоположения(ов), из которых пользователь или агент пользователя может выбрать наиболее подходящий. Формат сущности определяется типом носителя задано в поле заголовка типа содержимого. *

последнее звучит более в соответствии со спецификацией Http, но мне совсем не ясно, что

ответ должен содержать объект содержащий список ресурсов характеристики и местоположение

средства.

рекомендации? Интерпретации?

7 77

7 ответов:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19

это просто разделенное двоеточием значение ключа.

ETag: "xyzzy"

это может быть любой тип текстовых данных - я обычно включаю строку JSON с идентификатором созданного элемента. Простота тестирования сама по себе делает его полезным.

ETag: "{ id: 1234, uri: 'http://domain.com/comments/1234', type: 'comment' }"

в этом примере идентификатор, uri и тип созданного элемента являются " характеристиками ресурса и расположение".

Я думаю atompub в формате API-интерфейс REST это отличный пример спокойного обслуживания. Смотрите фрагмент ниже из спецификации atompub:

POST /edit/ HTTP/1.1
Host: example.org
User-Agent: Thingio/1.0
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Type: application/atom+xml;type=entry
Content-Length: nnn
Slug: First Post

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
</entry>

сервер сигнализирует об успешном создании с кодом состояния 201. Ответ включает заголовок местоположения, указывающий URI записи-члена записи Atom, и представление этой записи в теле ответа.

HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml;type=entry;charset="utf-8"
Location: http://example.org/edit/first-post.atom
ETag: "c180de84f991g8"  

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
  <link rel="edit"
      href="http://example.org/edit/first-post.atom"/>
</entry>

запись, созданная и возвращенная коллекцией, может не соответствовать учтенной записи от клиента. Сервер может изменять значения различных элементов в записи, таких как значения atom:id, atom:updated и atom:author, а также может удалять или добавлять другие элементы и атрибуты или изменять содержимое элемента и значения атрибутов.

идея заключается в том, что тело ответа дает вам страницу, которая связывает вас с вещью:

201 создан

201 (созданный) код состояния указывает, что запрос был выполнен и привел к созданию одного или нескольких новых ресурсов. Первичный ресурс, созданный запросом, идентифицируется либо полем заголовка местоположения в ответе, либо, если поле местоположения не получено, действующим запросом УРИ.

это означает, что вы включили бы Location в ответ заголовок это дает URL-адрес, где вы можете найти вновь созданный вещь:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597

ответ тела

затем они сказали, что вы должны включить в ответ тело:

полезная нагрузка ответа 201 обычно описывает и ссылается на ресурс(ы) создан.

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

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: text/html

Your answer has been saved! 
Click <A href="/a/36373586/12597">here</A> to view it.

если страница будет использоваться только роботом, то имеет смысл, чтобы ответ был машиночитаемым:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/xml

<createdResources>
   <questionID>1860645</questionID>
   <answerID>36373586</answerID>
   <primary>/a/36373586/12597</primary>
   <additional>
      <resource>http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586</resource>
      <resource>http://stackoverflow.com/a/1962757/12597</resource>
   </additional>
</createdResource>

или, если вы предпочитаете:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/json

{ 
   "questionID": 1860645, 
   "answerID": 36373586,
   "primary": "/a/36373586/12597",
   "additional": [
      "http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586",
      "http://stackoverflow.com/a/36373586/12597"
   ]
}

ответ полностью зависит от вас; это произвольно то, что вы хотели бы.

кэширование

наконец есть оптимизация, которую я могу предварительно кэшировать созданный ресурс (потому что у меня уже есть контент; я только что загрузил его). Сервер может вернуть дату или ETag, который я могу хранить с контентом, который я только что загрузил:

посмотреть 7.2 для обсуждения значения и назначения полей заголовка валидатора, таких как ETag и Last-Modified, в ответе 201.

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/23704283/12597
Content-Type: text/html
ETag: JF2CA53BOMQGU5LTOQQGC3RAMV4GC3LQNRSS4
Last-Modified: Sat, 02 Apr 2016 12:22:39 GMT 

Your answer has been saved! 
Click <A href="/a/36373586/12597">here</A> to view it.

и ETag s являются чисто произвольными ценности. Если они будут отличаться при изменении ресурса (и кэши должны быть обновлены) - это все, что имеет значение. ETag обычно представляет собой хэш (например, SHA2). Но это может быть база данных rowversion, или увеличивающийся номер редакции. Все, что будет изменить когда вещь изменения.

проверить HTTP: определения методов: POST.

действие, выполняемое методом POST, может не привести к ресурсу, который может быть идентифицирован URI. В этом случае либо 200 (OK), либо 204 (No Content) является соответствующим состоянием ответа, в зависимости от того, включает ли ответ объект, описывающий результат.

Если ресурс был создан на исходном сервере, ответ должен быть 201 (создан) и содержать сущность, которая описывает состояние запроса и ссылается на новый ресурс, и заголовок Location (см. раздел 14.30).

в нескольких словах:

  • 200 при создании объекта и вернулся
  • 201 когда объект создается, но возвращается только его ссылка (например, идентификатор или ссылка)

вывод фактически зависит от запрашиваемого типа контента. Однако, как минимум, вы должны поместить ресурс, который был создан в месте. Так же, как и шаблон Post-Redirect-Get.

в моем случае я оставляю его пустым, пока не попросит об ином. Так как это поведение JAX-RS при использовании ответа.создан.)(

однако, просто обратите внимание, что браузеры и фреймворки, такие как Angular, не следуют 201 автоматически. Я отметил поведение в http://www.trajano.net/2013/05/201-created-with-angular-resource/

еще один ответ, который у меня был бы для этого, - это прагматичный подход и сохранить ваш REST API contract простой. В моем случае я переработал свой REST API, чтобы сделать вещи более тестируемыми, не прибегая к JavaScript или XHR, просто простые HTML-формы и ссылки.

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

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