web-dev-qa-db-ja.com

REST 検証失敗または無効な複製のためのHTTPステータスコード

私はRESTベースのAPIを使ってアプリケーションを構築していて、各リクエストのステータスコードを指定するようになりました。

検証に失敗したリクエスト、またはリクエストがデータベースに複製を追加しようとしている場合は、どのステータスコードを送信すればよいですか。

私は http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlを見ました しかし、どれも正しいとは思えません。

ステータスコードを送信するときに一般的な方法はありますか?

729
alexn

入力検証失敗の場合: 400不正な要求 +あなたのオプションの説明。これは " RESTful Webサービス "という本で提案されています。二重送信の場合: 409矛盾


2014年6月に更新

関連する仕様は以前は RFC2616 でしたが、これは400(Bad Request)の使用をかなり狭く制限しています。

不正な構文のため、要求をサーバーで理解できませんでした

それで - それは おそらく それは意味論的誤りには不適切であると主張されてきた。もうそうじゃない; 2014年6月から、以前のRFC2616に取って代わる関連規格 RFC 7231400(Bad Request) の使用を与えています

クライアントエラーと見なされるものが原因で、サーバが要求を処理できない、または処理しない

696
deamon
  • 検証に失敗しました:403許可されていません( "サーバーは要求を理解しましたが、それを満たすことを拒否しています")。一般的な意見とは反対に、RFC2616は「403は認証失敗のためだけのものである」と言っているのではなく、「403:欲しいものはわかっていますが、そうはしていません」。その状態は認証によるものでもそうでなくてもよいです。
  • 重複を追加しようとしています:409 Conflict( "リソースの現在の状態と競合するため、要求を完了できませんでした。")

あなたは間違いなく(例えばカスタムヘッダ - X-Status-Reason: Validation failedのように)レスポンスヘッダや本文にもっと詳細な説明を与えるべきです。

264
Piskvor

ステータスコード422、 "Unprocessable Entity"

11.2。 422処理不能なエンティティ

422(Unprocessable Entity)ステータスコードは、サーバーが要求エンティティのコンテンツタイプを理解しているため(415(Unsupported Media Type)ステータスコードは不適切です)、要求エンティティの構文は正しい(したがって400(Bad Request)です) )ステータスコードは不適切ですが、含まれている命令を処理できませんでした。例えば、このエラー状態は、XML要求本体が整形式(すなわち、構文的には正しい)だが意味的に誤りのあるXML命令を含む場合に発生する可能性がある。

184
Julian Reschke

200、300、400、500はすべて非常に一般的です。あなたがジェネリックが欲しいならば、400はOKです。

422はますます多くのAPIで使用されており、そのままRailsでも使用されています。

APIにどのステータスコードを選択しても、誰かが同意しません。私は '400 +テキストステータス'は一般的すぎると考えているので、422を好みます。また、あなたはJSON対応のパーサーを利用していません。これとは対照的に、JSON応答を持つ422は非常に明示的であり、大量のエラー情報を伝えることができます。

JSONレスポンスと言えば、この場合のRailsエラーレスポンスを標準化する傾向があります。

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

この形式はフォームの検証に最適です。私は「エラー報告の豊富さ」の観点から、これをサポートするための最も複雑なケースを検討します。あなたのエラー構造がこれであるならば、それはおそらくあなたのエラー報告ニーズの全てを扱うでしょう。

76
sethcall

データベース内の重複は409 CONFLICTであるべきです。

検証エラーには422 UNPROCESSABLE ENTITYを使用することをお勧めします。

私はここで4xxコードのより長い説明を与える: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/ /

34
Phil Parker

200

Ugh ...(309、400、403、409、415、422)... 成功したHTTPリクエストだがREST callに失敗しました。

HTTPステータスコードとRESTステータスコードを混在させるのは 間違った です。

しかしながら、私は多くの実装がそれらを混ぜ合わせているのを見ました、そして、多くの開発者は私に同意しないかもしれません。

HTTP戻りコードはHTTP Request自体に関連しています。 REST呼び出しは、ハイパーテキスト転送プロトコル(Hypertext Transfer Protocol)要求を使用して行われ、呼び出されたRESTメソッド自体よりも低いレベルで機能します。 RESTは概念/アプローチであり、その出力はbusiness/logicalresult)ですが、HTTP結果コードはtransportone)です。

たとえば、/ users /を呼び出すときに "404 Not found"を返すのは混乱します。

  • URIが間違っている(HTTP)
  • ユーザーが見つかりません(REST)

「403禁止/アクセスが拒否されました」とは、

  • 特別な許可が必要です。ブラウザはユーザ/パスワードを尋ねることによってそれを処理できます。 (HTTP)
  • サーバーに誤ったアクセス許可が構成されています。 (HTTP)
  • 認証される必要があります(REST)

そしてリストは「500サーバーエラー」(Apache/Nginx HTTPスローエラーまたはRESTでのビジネス制約エラー)または他のHTTPエラーなどで続きます。

コードから、失敗の原因、HTTP(トランスポート)の失敗、またはREST(論理)の失敗が何であるかを理解するのは困難です。

HTTPリクエストが正常に実行された場合、レコードが見つかったかどうかにかかわらず、alwaysreturn 200 code)になります。URIリソースはfoundでHTTPサーバーによって処理されたためです。 HTTPの結果として200を含む空のWebページを受信することは可能ですか?

これの代わりにあなたはいくつかのオプションで200 HTTPコードを返すかもしれません:

  • 何かがうまくいかなかった場合のJSON結果の "error"オブジェクト
  • レコードが見つからない場合は空のJSON配列/オブジェクト
  • より良い処理のための以前のオプションと組み合わせたブール結果/成功フラグ。

また、インターネットプロバイダによってはあなたの要求を傍受して404 HTTPコードを返すことがあります。これはあなたのデータが見つからないという意味ではありませんが、トランスポートレベルでは問題があります。

から ウィキ

2004年7月、英国の通信事業者BT GroupはCleanfeedコンテンツブロックシステムを導入しました。このシステムは、Internet Watch Foundationによって違法とされる可能性があると識別されたコンテンツに対するリクエストに対して404エラーを返します。他のISPは、同じ状況でHTTP 403「禁止」エラーを返します。検閲を隠すための手段として偽の404エラーを採用することも、タイとチュニジアで報告されています。 2011年の革命以前に検閲が厳しかったチュニジアでは、人々は偽の404エラーの性質に気付き、「見えない検閲官」を表す「Ammar 404」という名前の架空の人物を作成しました。

このようなもので単純に答えてみませんか?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

たとえリクエストが論理的に失敗したとしても、GoogleはジオコーディングAPIのステータスコードとして常に200を返します: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

たとえRESTリクエストが失敗したとしても、Facebookは成功したHTTPリクエストに対して常に200を返します: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling

それは簡単です、HTTPステータスコードはHTTPリクエスト用です。 REST AP​​Iはあなたです、あなたのステータスコードを定義します。

20
Marcodor

Ember-DataのActiveRecordアダプタは、422 UNPROCESSABLE ENTITYがサーバーから返されることを期待しています。あなたのクライアントがEmber.jsで書かれているのであれば、422を使うべきです。そうしないとDS.Errorsには返されたエラーが入りません。 もちろん、422を他のコードに変更することもできます あなたのアダプタで。

7
Daniel Kmak

ステータスコード304未変更 重複した要求に対しても受け入れ可能な応答を行います。これはエンティティタグを使ってIf-None-Matchのヘッダを処理するのと似ています。

私の意見では、@ Piskvorの答えは私が最初の質問の意図であると感じるものにもっと明白な選択ですが、私はまた関連がある代替案を持っています。

重複したリクエストをエラーとしてではなく警告または通知として扱う場合は、応答ステータスコード304 Not Modifiedおよび既存のリソースを識別するContent-Locationヘッダーも同じように有効です。目的が単にリソースが存在することを確認することである場合、重複要求はエラーではなく確認になります。要求は間違っていませんが、単に冗長であり、クライアントは既存のリソースを参照できます。

つまり、要求は正常ですが、リソースがすでに存在するため、サーバーはそれ以上処理を実行する必要はありません。

6
Suncat2000