HTTP URLに投稿しているJSONリクエストがあります。
これはrequestedResource
フィールドが存在するが400
がこのフィールドには無効な値である"Roman"
として扱うべきですか?
[{requestedResource:"Roman"}]
これは400
フィールドがまったく存在しない"blah"
として扱うべきですか?
[{blah:"Roman"}]
400は、リクエストが不正な形式であることを意味します。つまり、クライアントからサーバーに送信されたデータストリームはルールに従いませんでした。
JSONペイロードを持つREST APIの場合、通常、400がJSONがサービスのAPI仕様に従って何らかの方法で無効であることを示すために使用されます。
その論理によって、あなたが提供したシナリオは両方とも400のはずです。
代わりにこれがJSONではなくXMLであったと想像してください。どちらの場合も、未定義の要素または不適切な要素値が原因で、XMLがスキーマ検証に合格することはありません。それは悪い要求です。ここでも同じです。
w3.org から
10.4.1 400不正なリクエスト
不正な構文のため、要求をサーバーで理解できませんでした。クライアントは変更なしにリクエストを繰り返すべきではありません(SHOULD NOT)。
HTTP応答コードを選択することは非常に簡単な作業であり、簡単な規則で説明できます。忘れられがちな唯一のトリッキーな部分は、RFC 7231の6.5項です。
HEAD要求に応答するときを除いて、サーバはエラー状況の説明とそれが一時的なものか恒久的なものかを含む表現を送るべきです(SHOULD)。
規則は以下のとおりです。
あなたのケースでは "Roman"がユーザー入力から取得され、クライアントが特定の反応を起こさなければならない場合、私は400エラーとこのような何かを返します。
{
"error_type" : "unsupported_resource",
"error_description" : "\"Roman\" is not supported"
}
開発者が何か間違ったことをしない限り、そのような状況がクライアントの悪い論理エラーであり、予期されていない場合、またはより一般的なエラー:
{
"error_type" : "malformed_json",
"error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}
どちらの場合も「構文の形式が正しくありません」。それは間違っている意味論です。したがって、私見400は不適切です。代わりに、{ "error": { "message": "Unknown request keyword" } }
などの何らかのエラーオブジェクトとともに200を返すことが適切です。
クライアント処理パスを検討してください。構文の誤り(例えば無効なJSON)はプログラムの論理の誤り、言い換えればある種のバグであり、それに応じて403と同じように扱われるべきです。言い換えれば、悪いことが間違っています。
一方、パラメータ値のエラーは、おそらく検証が不十分なユーザー入力が原因で、セマンティクスのエラーです。それはHTTPエラーではありません(私はそれが422であることができると思いますが)。処理パスは異なります。
たとえば、jQueryでは、500とアプリケーション固有のセマンティックエラーの両方を処理する単一のエラーハンドラを作成する必要はありません。 Emberのような他のフレームワークも400と500のようなHTTPエラーを同じように大きな致命的な失敗として扱い、プログラマーはそれが「本当の」エラーであるかどうかに応じて何が起こっているかを検出し分岐する必要がある。
request が不正な形式であることを示す以外の目的で400
ステータスコードを使用することは明らかに間違っています。
リクエストペイロードにapplication/json
として解析できなかったバイトシーケンスが含まれている場合(サーバーがそのデータフォーマットを期待している場合)、適切なステータスコードは415
です。
要求のエンティティが、要求されたメソッドの要求されたリソースでサポートされていない形式であるため、サーバーは要求の処理を拒否しています。
要求ペイロードが構文的には正しいが意味的には正しくない場合は、非標準の422
応答コード、または標準の403
ステータスコードを使用できます。
サーバーは要求を理解しましたが、それを満たすことを拒否しています。承認は助けにならないでしょうし、要求は繰り返されるべきではありません。
期待について考えてください。
クライアントアプリとして、あなたは何かがサーバー側でうまくいかないかどうかを知ることを期待しています。 blah
が欠落しているか、requestedResource
の値が正しくない場合にサーバーがエラーをスローする必要がある場合は、400エラーが適切です。
最初に間違っている可能性があるURLを確認し、正しい場合は送信しているリクエスト本文を確認してください。考えられる原因は、送信しているリクエストに正しい構文がないことです。
詳しく述べるには、リクエスト文字列の中の特殊文字を調べてください。それが(特殊文字)使用されている場合、これがこのエラーの根本的な原因です。
リクエストをコピーして、すべてのタグデータを分析してみてください。
補足として、私と同じ問題に遭遇するかもしれない人のために、私は$.ajax
を使用してフォームデータをサーバーに送信していますが、最初は400
エラーも発生していました。
JavaScript変数があるとします。
var formData = {
"name":"Gearon",
"hobby":"Be different"
};
以下のように、変数formData
をキーdata
の値として直接使用しないでください。
$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: formData,
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});
代わりに、JSON.stringifyを使用して、以下のようにformData
をカプセル化します。
$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: JSON.stringify(formData),
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});
とにかく、他の人が説明したように、エラーはサーバがリクエストの不正な構文の原因を認識できなかったためです。私は実際にインスタンスを生成しています。それが誰かに役立つことを願っています。