クライアントがオブジェクトを保存できるようにするサーバーを構築しています。これらのオブジェクトは完全にクライアント側で構築され、オブジェクトの全存続期間にわたって永続的なオブジェクトIDを完備しています。
クライアントがPUTを使用してオブジェクトを作成または変更できるように、APIを定義しました。
PUT /objects/{id} HTTP/1.1
...
{json representation of the object}
{id}はオブジェクトIDなので、Request-URIの一部です。
さて、私はクライアントがPOSTを使ってオブジェクトを作成することを許可することも検討しています。
POST /objects/ HTTP/1.1
...
{json representation of the object, including ID}
POSTは "追加"操作を意味しているので、オブジェクトが既に存在している場合に何をすべきかわかりません。リクエストを修正リクエストとして扱うべきですか、それとも何らかのエラーコードを返すべきですか(どちらがいいですか)。
私の感情は409 Conflict
であることが最も適切ですが、当然のことながらほとんど見られません。
リソースの現在の状態と競合しているため、要求を完了できませんでした。このコードは、ユーザーが競合を解決してリクエストを再送信できる可能性があると予想される状況でのみ許可されます。レスポンスボディは衝突の原因をユーザが認識するのに十分な情報を含むべきである[SHOULD]。理想的には、レスポンスエンティティは、ユーザーまたはユーザーエージェントが問題を解決するのに十分な情報を含むでしょう。ただし、それは不可能である可能性があり、必須ではありません。
競合は、PUT要求に応答して発生する可能性が最も高いです。たとえば、バージョン管理が使用されていて、PUTされているエンティティに、以前の(サードパーティの)要求によって行われたものと競合するリソースへの変更が含まれている場合、サーバーは409応答を使用して要求を完了できないことを示します。 。この場合、レスポンスエンティティはレスポンスContent-Typeで定義されたフォーマットで2つのバージョン間の違いのリストを含むでしょう。
RFC 7231 によると、 303他を参照 {を使用してもよいPOSTの処理結果が既存のリソースの表現と等価になる場合。
個人的にはWebDAVの拡張子422 Unprocessable Entity
を使います。
422 Unprocessable Entity
ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解しているため(つまり、415 Unsupported Media Type
ステータスコードは不適切です)、リクエストエンティティの構文は正しい(したがって、400 Bad Request
ステータスコードは不適切です)が、含まれているコンテンツを処理できませんでした。説明書.
REST APIを作成しようとしている間、ゲームに遅れるかもしれませんが、私はこの意味論の問題につまずいた。
Wrikkenの答えを少し拡張するには、状況に応じて409 Conflict
または403 Forbidden
のどちらかを使用できると思います。つまり、競合を解決して要求を完了するためにユーザーがまったくできない場合は403エラーを使用します。明示的にリソースを削除するためにDELETE
リクエストを送信するか、何らかの可能性がある場合は409を使用します。
10.4.4 403禁止
サーバーは要求を理解しましたが、それを満たすことを拒否しています。承認は助けにならないでしょうし、要求は繰り返されるべきではありません。リクエストメソッドがHEADではなく、リクエストが満たされなかった理由をサーバが公表したい場合は、エンティティ内で拒否された理由を説明する必要があります。サーバーがこの情報をクライアントが利用できるようにしたくない場合は、代わりにステータスコード404(Not Found)を使用できます。
今日では、誰かが "403"と言ってパーミッションや認証の問題が頭に浮かぶが、その仕様では基本的にサーバーには実行しないように指示し、再度要求しないようにしている。じゃない。
PUT
vs. POST
...についてPOST
は、ユーザーがリソースの識別子を作成する手段がない、または作成すべきでない場合に、リソースの新しいインスタンスを作成するために使用されるべきです。 PUT
は、リソースのIDがわかっているときに使用されます。
9.6 PUT
...
POSTとPUTリクエストの基本的な違いは、Request-URIの意味の違いに反映されています。 POST要求内のURIは、囲まれたエンティティを処理するリソースを識別します。そのリソースは、データ受け入れプロセス、他のプロトコルへのゲートウェイ、または注釈を受け入れる別のエンティティなどです。対照的に、PUTリクエストのURIはリクエストに同封されたエンティティを識別します - ユーザエージェントはどんなURIが意図されているか知っていて、サーバはリクエストを他のリソースに適用しようと試みてはいけません。サーバが要求が異なるURIに適用されることを望む場合、
それは301(永久に動かされた)応答を送らなければなりません;ユーザエージェントはそれからリクエストをリダイレクトするかどうかに関してそれ自身の決定をするかもしれません。
"302 Found"は私には論理的に思えます。そして RFC 2616 はそれがGETとHEAD以外の他の要求に対しても答えることができると言います(そしてこれは確かにPOSTを含みます)
しかしそれでも、訪問者はこの "Found"リソースを取得するためにRFCによってこのURLにアクセスし続けます。本物の "Found" URLに直接移動するには、 "303 See Other"を使用する必要がありますが、これは理にかなっていますが、次のURLをGETするための呼び出しを強制します。良い面では、このGETはキャッシュ可能です。
私は "303 See Other" を使用すると思います。私は私がボディで見つけられる「事」と答えることができるかどうか知らないが、私はサーバーへの1往復を節約するためにそうしたいと思う。
更新: RFCを読み直した後も、 存在しない "4XX + 303 Found"のコードが正しいはずです。しかし、 "409 Conflict"は既存の最良の回答コード (@ Wrikkenが指す)で、おそらく既存のリソースを指すLocationヘッダーを含みます。
418を返すことについてはどうですか?
クライアントはすでにサーバー上に存在するエンティティを永続化するよう要求するので、サーバーはついに狂って彼が急須であると思い、418 I'm a teapot
を返します。
参考文献:
私はあなたがこれをすべきだとは思わない。
POSTは、ご存知のとおり、コレクションを変更するためのもので、新しい項目を作成するために使用されます。ですから、もしあなたがidを送ったら(それは良い考えではないと思います)、あなたはコレクションを修正するべきです、すなわちアイテムを修正するべきです、しかしそれは混乱します。
IDなしでアイテムを追加するために使用します。それはベストプラクティスです。
PUTリクエストの場合と同じように、(IDではなく)UNIQUE制約を取り込む場合は、409と応答できます。しかしIDではありません。
RESTについては、あなたはその特定のシステムの振る舞いについて決定を下さなければならないと思います。その場合、私は「正しい」答えがここで与えられるいくつかの答えのうちの1つになると思います。リクエストを停止して、続行する前にクライアントが修正する必要があると間違えたように動作させる場合は、409を使用します。競合がそれほど重要ではなく、リクエストを続行したい場合は、リダイレクトして応答します。見つかったエンティティへのクライアント。とにかく、適切なREST APIがPOSTに続いてそのリソースのGETエンドポイントにリダイレクト(または少なくともロケーションヘッダーを提供)すべきだと思うので、この動作は一貫した経験を与えるでしょう。
編集:それはあなたがIDを提供しているのであなたはPUTを考慮すべきであることも注目に値する。それで、振る舞いは単純です:「私は今そこにあるものを気にしないで、このことをそこに置きなさい」。つまり、何もない場合は作成されます。何かがあればそれは置き換えられます。サーバがそのIDを管理するときはPOSTがより適切であると思います。 2つの概念を分けることは基本的にそれをどのように扱うかをあなたに教えます(すなわちPUTは冪等性であるのでペイロードが検証する限り常に働くべきです、POSTは常にIDの衝突があるなら409はその衝突を説明するでしょう)。
それはすべて context についてであり、また誰がリクエストに重複しているかについて責任があります(サーバーまたはクライアントあるいは両方)
サーバーが だけ複製を指す場合 、4xxを見てください。
暗黙の 重複の処理については、2XXを見てください。
サーバーが 何かを返すことが期待されている場合 、3XXを見てください。
サーバーが既存のリソースを指すことができる場合、それはリダイレクトを意味します。
上記の方法では不十分な場合は、応答の本文にエラーメッセージを用意することをお勧めします。
なぜ 202受け入れられない ?それはOKリクエスト(200秒)、クライアントエラーはありません(400秒)、それ自体です。
から 10ステータスコードの定義 :
「202受け入れられました。要求は処理のために受け入れられましたが、処理は完了しませんでした。」
...すでに存在しているので、完成する必要はありません。クライアントはそれがすでに存在していることを知りません、彼らは何も悪いことをしませんでした。
私は202を投げて、GET /{resource}/{id}
が返していたものと同様の内容を返すことに傾いています。
私は422 Unprocessable Entity
を使います。これはリクエストが無効だが問題が構文や認証にない場合に使われます。
他の答えに対する議論として、非4xx
エラーコードを使用することはそれがクライアントエラーではないことを意味するでしょう、そしてそれは明らかにそうです。クライアントエラーを表すためにnon -4xx
エラーコードを使用することはまったく意味がありません。
ここでは409 Conflict
が最も一般的な答えであるように思われますが、仕様によると、これはリソースが既に存在し、それに適用している新しいデータが現在の状態と互換性がないことを意味します。たとえば、すでに取得済みのユーザー名を使用してPOST
リクエストを送信している場合、ターゲットリソースはまだ投稿されていないので、実際にはターゲットリソースと競合しません。保管されているリソースのバージョンと要求されているリソースのバージョンとの間に矛盾がある場合、これは特にバージョン管理のエラーです。たとえばクライアントが古いバージョンのリソースをキャッシュしていて、条件付きで有効ではなくなったその誤ったバージョンに基づいて要求を送信した場合など、その目的に非常に役立ちます。 「この場合、応答表現には、改訂履歴に基づいて差異をマージするのに役立つ情報が含まれている可能性があります。」そのユーザ名で別のユーザを作成する要求は処理不可能で、バージョン管理とは関係ありません。
レコードの場合、422は、すでに使用されている名前でリポジトリを作成しようとしたときにGitHubが使用するステータスコードでもあります。
もう一つの可能性のある治療法は結局パッチを使用しています。 PATCHは、内部状態を変更するものとして定義され、追加に限定されません。
PATCHを使用すると、既存の項目を更新することで問題を解決できます。参照してください: RFC 5789:パッチ
208 - http://httpstatusdogs.com/208-already-reported についてはどうですか?それは選択肢ですか?
私の意見では、唯一のものがリソースの繰り返しである場合、エラーは発生しません。結局のところ、クライアント側にもサーバー側にもエラーはありません。
重複レコードの正しいコードをチェックしているときに、この質問につまずいた。
私の無知を許しなさいしかし私はなぜ誰もが明らかに「複数選択」または「あいまい」を言うコード「300」を無視しているのか理解していない
私の意見では、これはあなた自身の使用のための非標準または特定のシステムを構築するための完璧なコードになるでしょう。私も間違っている可能性があります。
おそらくそれは400 Bad Request
です
6.5.1。400不正な要求
400(Bad Request)ステータスコードは、クライアントエラーと見なされるもの(たとえば、不正な形式の要求構文、無効な要求メッセージのフレーミング、不正な要求など)が原因で、サーバーが要求を処理できないか処理できないことを示します。ルーティング)。
要求に重複した値(すでに存在する値)が含まれているため、それはクライアントエラーとして認識される可能性があります。次の試行の前にリクエストを変更する必要があります。
これらの事実を考慮することで、HTTP STATUS 400 Bad Requestとして結論付けることができます。