Создайте запрос с POST, кодами ответа 200 или 201 и содержимым

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

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

http://myhost/serviceX/someResources

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

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

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

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

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

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

средства.

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

7 ответов


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

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

ETag:"xyzzy"

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

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

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


Я думаю atompub в формате API-интерфейс REST - это отличный пример RESTful-сервис. См. фрагмент ниже из спецификации 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, или увеличивающийся номер редакции. Все, что угодно ... --21-->изменить когда вещь изменения.


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

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

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


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

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

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

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

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


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

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

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