応答コード200または201とコンテンツを含むPOSTを使用してリクエストを作成します


125

新しいデータ項目をシステムに追加することを目的としたRESTサービスを作成するとします。

にPOSTする予定です

http://myhost/serviceX/someResources

それが機能する場合、どの応答コードを使用する必要がありますか?そして、どんなコンテンツを返せますか。

私はHTTP応答コードの定義を調べており、これらの可能性を確認しています。

200:アクションの結果を説明または含むエンティティを返します。

201:CREATEDを意味します。意味*リクエストが満たされ、新しいリソースが作成されました。新しく作成されたリソースは、応答のエンティティで返されるURIで参照できます。リソースの最も具体的なURIは、Locationヘッダーフィールドで指定されます。レスポンスには、ユーザーまたはユーザーエージェントが最も適切なものを選択できるリソースの特性と場所のリストを含むエンティティを含める必要があります(SHOULD)。エンティティ形式は、Content-Typeヘッダーフィールドで指定されたメディアタイプによって指定されます。*

後者の方がHttp仕様に沿っているように思われますが、何が原因なのかまったくわかりません

応答には、リソースの特性と場所のリストを含むエンティティを含める必要があります(SHOULD)。

手段。

推奨事項?解釈?

回答:


77

アイデアは、レスポンスボディがあなたに事にリンクするページを与えるということです:

201作成されました

201(作成済み)ステータスコードは、要求が満たされ、1つ以上の新しいリソースが作成されたことを示します。リクエストによって作成されたプライマリリソースは、レスポンスのLocationヘッダーフィールドによって識別されます。Locationフィールドが受信されない場合は、有効なリクエストURIによって識別されます。

これは、新しく作成されたものを見つけることができる場所のURLをLocation示す応答ヘッダーにを含めることを意味します。

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="https://stackoverflow.com/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を返すことができます。

201応答のETagやLast-Modifiedなどのバリデーターヘッダーフィールドの意味と目的については、セクション7.2を参照してください。

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="https://stackoverflow.com/a/36373586/12597">here</A> to view it.

そしてETagsは純粋に任意の値です。リソースが変更されたときに(そしてキャッシュを更新する必要があるときに)それらを異なるものにすることはすべて問題です。ETagは通常、ハッシュです(SHA2など)。ただし、データベースrowversionまたはインクリメントするリビジョン番号の場合もあります。物事変化したときに変化するもの


これまでのところ、あなたの反応は最も賢明なようです。応答のオントロジーについては少し心配ですが、それを除けば、それは仕様の最も成熟した解釈のようです。人/機械の出力を処理するための軽量の「応答性の高い」方法があるかどうか知りたいです。しかし、ほとんどの場合、「独自の入力をキャッシュする」という提案に興味をそそられます。私が知っているほとんどのWebアプリは、リソースの1:1バージョンを作成しません。文字列の大文字の正規化のような些細なことでも。送信されたバージョンをetagが作成されたバージョンとして扱うのは少しおかしくないですか?
アンソニー

1
@Anthony、キャッシング:1対1のファイルストレージアプリケーションのようなものです。たとえばWebDAV PUT&POSTを比較してください。処理される巨大なファイル。
kxr 2017年

@Anthony ETagをクライアントに返したいかどうかはあなた次第です。クライアントアップロードしたばかりのコンテンツが保存したものと異なる場合は、ETagを返さないでください。それはあなたの柔軟性とあなたの選択です。
イアン・ボイド

回答にContent-Lengthがないのはなぜですか?
Vinnie Falco

1
@VinnieFalcoこれは、201応答コードに関する回答です。Content-Lengthは、説明のために省略されています。
Ian Boyd

91

atompub REST APIは、安らかなサービスの良い例だと思います。以下の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で正常に作成されたことを通知します。応答には、AtomエントリのメンバーエントリURIを示すLocationヘッダーと、応答の本文にあるそのエントリの表現が含まれます。

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>

コレクションによって作成および返されたエントリは、クライアントによってPOSTされたエントリと一致しない場合があります。サーバーは、atom:id、atom:updated、atom:authorの値など、エントリ内のさまざまな要素の値を変更できます(MAY)。他の要素と属性を削除または追加するか、要素のコンテンツと属性値を変更できます。


9
リソースがギガバイトの大きさである場合、作成されたリソースを返すのは少し時間がかかるかもしれません...
Tor Valamo

10
同意しました!それは必要性の最適化です-しかし、あなたはそれを時期尚早にしたくありません。安らぎの精神でデザインし、必要なときだけ例外を作ることが重要です。
Chandra Patni

3
@ChandraPatni、アトムは死んだ。より良い例が必要です。
Pacerier、2015年

16
アトムは死んでいる可能性がありますが、この例の精神はまだ見られています。
Ashimema 2015年

2
201応答の私の最初の解釈は、「ねえ、あなたはリソースを作成したかったが、コンテキストに基づいて、最終結果に興味がなかったか、またはこのリソースへの書き込みアクセス権はあるが読み取りアクセス権がないかのどちらかでした。どちらでも、場合、メインコレクションに戻る前に必要なのは、作成されたリソースのURLだけです。証拠として作成されました。」それを超えると、基本的に200応答のように見えます。RFCが別のことを考えていたのでなければ
アンソニー

50

一言で言えば:

  • オブジェクトが作成され返される200
  • 201オブジェクトが作成されたが、その参照のみが返された場合(IDやリンクなど)

これのソース?
sudo soul


3
tools.ietf.org/html/rfc7231#section-6.3.1を読んだ後、私はこの理解に同意します-私はあなたがどうやってそれに到達したのかについてもっと尋ねていたと思います。しかし、私の理解では... 200 =リソースが作成されて返されました| 201 =リソースが作成され、参照が返されます| 204 =リソースが作成され、ペイロードが返されない
sudo soul

34

HTTP:メソッド定義:POSTを確認してください。

POSTメソッドによって実行されるアクションは、URIで識別できるリソースにならない場合があります。この場合、応答に結果を説明するエンティティが含まれているかどうかに応じて、200(OK)または204(コンテンツなし)が適切な応答ステータスです。

オリジンサーバーでリソースが作成されている場合、応答は201(作成済み)である必要があり、リクエストのステータスを記述し、新しいリソースを参照するエンティティとLocationヘッダー(セクション14.30を参照)を含む必要があります。


18

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

コロンで区切られたKey-Valueです。

ETag:「xyzzy」

任意のタイプのテキストデータを使用できます。通常、作成したアイテムの識別子を含むJSON文字列を含めます。単独でのテストの容易さは、それを含める価値があります。

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

この例では、作成されたアイテムの識別子、URI、およびタイプが「リソースの特性と場所」です。


3
ETagは、リソースの特性と場所のリストを含むエンティティに対応すると言っています。私はあなたの提案が良いことを見ることができます、テストについてのあなたのポイントに非常に同意します。ただし、これが「リソースの特性と場所のリスト」にどのように適合するかはわかりません。
djna 2009

「リソースの特性と場所のリスト」は、提供されるあらゆるデータ構造のコンテンツです。より厳密な実装は、JSON構造にリソースuriとおそらく作成されたリソースのタイプを含めることです。そのように答えを調整します。
テンパイア2009

7
人々が学ぶことができるように、問題を明記してください。そうでなければ、コメントはただ手を振っています。
2013年

@SimonGibbsどのような問題ですか?
MEMark 2014

2
仕様では厳密に正しいですが、非常に珍しい実装オプションをお勧めします。また、ページの上部にある質問には実際には回答しません(または、ETagとエンティティの単語を混同することで回答します)。43票の回答の方が良いでしょう。
Simon Gibbs

1

出力は、実際には要求されているコンテンツタイプによって異なります。ただし、少なくとも場所で作成されたリソースを配置する必要があります。Post-Redirect-Getパターンと同じです。

私の場合、別の方法で要求されるまで空白のままにします。それはResponse.created()を使用するときのJAX-RSの動作です。

ただし、Angularなどのブラウザやフレームワークは201に自動的には従わないことに注意してください。私はhttp://www.trajano.net/2013/05/201-created-with-angular-resource/で動作を確認しました


-2

これについて私が持つ別の答えは、実用的なアプローチを取り、REST APIコントラクトをシンプルに保つことです。私の場合、私はREST APIをリファクタリングして、JavaScriptやXHRに頼らずに単純なHTMLフォームとリンクだけを使用して物事をテストしやすくしました。

上記の質問をより具体的にするために、戻りコードを使用します 200をして、返されたメッセージにアプリケーションが理解できるJSONメッセージを含めます。ニーズによっては、Webアプリケーションが別の呼び出しでデータを取得できるように、新しく作成されたオブジェクトのIDが必要になる場合があります。

リファクタリングされたAPI契約では、POSTは実際にはキャッシュできないため、POST応答にはキャッシュ可能なデータを含めないでください。そのため、GETリクエストを使用してリクエストおよびキャッシュできるIDに制限してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.