JSONエンコードされたデータの形式でリクエスト内のクエリパラメータを受け入れるRESTful APIを開発しています。
要求されていない/予期されていないパラメーターが必要なパラメーターと共に渡された場合の正しい動作は何なのかと思っていました。
たとえば、特定のエンドポイントのPUTリクエストで、キーnameとsurnameにそれぞれ2つの値を提供する必要がある場合があります。
{
"name": "Jeff",
"surname": "Atwood"
}
以下の例のcolorのように、偽のキーも渡された場合はどうなりますか?
{
"name": "Jeff",
"surname": "Atwood",
"color": "red"
}
colorの値は予期されておらず、文書化もされていません。
それを無視するか、BAD_REQUEST 400ステータスエラーでリクエストを拒否しますか?
ドキュメントに準拠していないため、リクエストが悪いと断言できます。そしておそらくAPIユーザーはそれについて警告されるべきです(彼女は値を渡しました、彼女はそれのために何かを期待します。)
しかし、必要なパラメーターがすべて提供されているため、要求を満たせるため、要求を受け入れることができると主張することもできます。
長年にわたって多数のベンダーのRESTful APIを使用してきたので、「ユーザー」の視点を説明しましょう。
多くの場合、ドキュメントは単に悪いか、古くなっています。たぶん、パラメータ名が変更された、プロパティ名に正確な大文字小文字の区別が強制された、ドキュメントで間違ったフォントを使用した、多分[〜#〜] i [〜#〜]lのように-はい、それらは異なる文字です。
無視しないでください。代わりに、プロパティ名をわかりやすいメッセージで示すエラーメッセージを送信します。たとえば、「不明なプロパティ名:color」のようになります。
これは、APIの消費に関するサポートリクエストを制限するのに大いに役立ちます。
明らかにAPIが正しく機能していないため、パラメータを単に無視すると、開発者はAPIの呼び出し中に有効な値が渡されていると考える可能性があります。
一般的なエラーメッセージをスローする場合、開発者は何が起こっているのかを理解しようとして、髪を引っ張ってフォーラムをあふれさせるでしょう。このサイトまたは電話は、サーバーが機能しない理由を尋ねる呼び出しをします。 (私は最近、404メッセージが誤ったパラメーターに対する有効な応答ではなく、ドキュメントに使用されている実際のパラメーター名が反映されていることを理解していないベンダーとこの問題を経験しました...)
同じトークンで、必須パラメーターが欠落している場合にも、適切なエラーメッセージが表示されることを期待しています。例 "必須プロパティ:名前がありません"。
基本的に、APIのコンシューマーが可能な限り自己満足できるように、できる限り役立つことを望んでいます。あなたが言うことができるように、私は心から「優雅な」対「厳しい」の内訳に同意しません。 「優雅」であるほど、APIのコンシューマーが彼らが正しいことをしている問題を抱える可能性が高くなりますが、 APIから予期しない動作が発生しています。人々が失敗する可能性のあるすべての方法を考えることはできないため、関連するエラーメッセージを厳密に遵守することは、非常に役立ちます。
API設計を行う場合は、「厳しい」または「優雅な」という2つのパスをたどることができます。
RESTは素晴らしい優雅なAPI設計を可能にし、私はこのパスをできるだけ長くたどり、私のクライアントにも同じことを期待します。 APIが進化した場合、特定のクライアントにのみ関連するパラメーターを応答に追加する必要があるかもしれません。私のクライアントが私に礼儀正しいなら、彼らはこれを扱うことができるでしょう。付け加えておきたいのは、厳しいAPIデザインの場所があるということです。デリケートなドメイン(現金取引など)で設計していて、クライアントとサーバーの間の誤解の余地を残したくない場合。次のPOSTリクエストを想像してください(/ account/{no}/transaction/APIで有効):
{ amount: "-100", currency : "USD" }
次の(無効なAPIリクエスト)をどうしますか?
{ amount: "100", currency : "USD", type : "withdrawal" }
「type」属性を単に無視する場合、それらを引き出す代わりに100 USDを入金します。そのようなドメインでは、私は厳しいアプローチに従い、何の恵みも見せません。
可能な場合は礼儀正しく、必要な場合は厳格にしてください。
更新:
ユーザーに通知する必要があるという @ Chris Livelyの回答 に完全に同意します。参照されているリソースのメッセージが明確であっても、常にエラーケースになることはありません。そうしないと、リソース表現の再利用が妨げられ、意味的に同一の情報の再パッケージ化が必要になります。
それはあなたのドキュメントに依存します。
しかし、一般的に言えば、ignore
だけです。他のほとんどのサーバーも、理解できなかった要求パラメーターを無視します。
以前の投稿からの例
REST API Url の追加クエリパラメータ
"" "Googleはここで2つの追加パラメーターを無視します https://www.google.com/#q=search+for+something&invalid=param&more=stuff 「」
無視してください。
エラーメッセージを通じてRESTful APIをリバースエンジニアリングする機会をユーザーに与えないでください。
開発者に最も親密で、最も明確で、最も包括的なドキュメントを提供し、APIが必要としサポートするパラメーターのみを解析します。
余分なパラメーターを無視することをお勧めします。 APIの再利用は、統合の世界におけるゲームチェンジャーです。同じAPIを他の統合で使用できるが、少し余分なパラメーターがある場合はどうなりますか?
アプリケーションAが期待するもの:
{
"name": "Jeff",
"surname": "Atwood"
}
アプリケーションBは、
{
"name": "Jeff",
"surname": "Atwood",
"color": "red"
}
「カラー」を無視する単純なgetアプリケーションアプリケーションAは、それを処理する2つの異なるAPIを持つのではなく、仕事をします。
次のJSONスキーマがあるとします。
{
"frequency": "YEARLY",
"date": 23,
"month": "MAY",
}
フリークエンシー属性は、「WEEKLY」、「MONTHLY」、および「YEARLY」の値を受け入れます。 「WEEKLY」頻度値の予想ペイロードは次のとおりです。
{
"frequency": "WEEKLY",
"day": "MONDAY",
}
また、「毎月」の頻度値に予想されるペイロードは次のとおりです。
{
"frequency": "MONTHLY",
"date": 23,
}
上記のJSONスキーマを指定すると、通常、逆シリアル化のために頻度、日、日付、月のフィールドを含むPOJOが必要になります。
受信したペイロードが次の場合:
{
"frequency": "MONTHLY",
"day": "MONDAY",
"date": 23,
"year": 2018
}
送信者の意図がわからないため、「day」属性でエラーをスローします。
「年」属性については、私には本当に選択肢がありません。その属性に対してエラーをスローしたい場合でも、できない場合があります。私のPOJOにはそのような属性がないので、JSONシリアライゼーション/デシリアライゼーションライブラリでは無視されます。そして、これはGSONの動作であり、設計上の決定を考えると理にかなっています。
逆シリアル化中のJsonツリーまたはターゲットタイプツリーのナビゲート
Json文字列を目的のタイプのオブジェクトに逆シリアル化する場合、入力のツリーまたは目的のタイプのタイプツリーをナビゲートできます。 Gsonは、ターゲットオブジェクトのタイプをナビゲートする後者の方法を使用します。これにより、期待しているオブジェクトのタイプのみをインスタンス化するという厳密な制御が維持されます(基本的に、予期される「スキーマ」に対して入力を検証します)。これを行うことにより、Json入力にあるが予期されなかった余分なフィールドも無視します。
Gsonの一部として、任意のオブジェクトを取得してそのフィールドをナビゲートし、選択したビジターを呼び出すことができる汎用のObjectNavigatorを作成しました。
GSON設計ドキュメント から抽出