web-dev-qa-db-ja.com

REST APIでは、サーバー側のユーザー入力を修正する必要がありますか?

クライアントからJSONデータを受け入れるエンドポイントを持つREST APIがあります。JSONフィールドの1つは、リソースに関連付けられたWebサイトページへのハイパーリンクとして他のユーザーに表示されるURLです。パイプラインのどこかで、URLが有効であることを確認する必要がありました(http(s)://で始まり、ホワイトリストのドメインが含まれているなど)。

そのため、有効なURLのみを受け入れ、URLが無効と見なされるとエラー(400)を返すようにAPIを設計しました。 UI側では、ユーザーはURLが有効になるまでURLを修正する必要があり、エラーメッセージはエラーケース(欠損値、無効なドメイン、無効な形式...)に適応します。

私たちの製品所有者は、稼働する前に実装をテストしましたが、この単純なアプローチに問題がありました。彼は「facebook.com/foobar」と入力し、URLが有効であることを期待していました。エラーメッセージは、「 https://www.example.com/xxxx "のような有効なURLを入力してください」のようなものでした。彼は、入力フィールドがブラウザのアドレスバーが受け入れるすべてのものを受け入れることを(かなり正しく)期待していました。エラーメッセージはより明確である可能性がありますが(「URLはhttp(s)://で始まる必要があります」)、彼が正しかったことと、この場合、ユーザー入力を保存する前にアプリケーションで修正する必要があることに同意しました。

ここには2つのアイデアがありました。

  • 保存時にAPIにURLを修正させる(デフォルトのプロトコルを付加する)か、
  • または、クライアント側でプロトコルを追加し、API検証には触れないでください。

REST APIはユーザー入力をサイレントに変更することは決してないはずです(APIを消費するクライアントの種類を知らず、ユーザーをサイレントに変更することは決してありません)。入力には予期しない副作用が生じる可能性があります。問題は、私の見解を裏付ける実際の例が見つからなかったことです。

それどころか、私のチームメイトの1人(修正の責任者)は、他の方法よりも1つの方法を好む正当な理由を見つけることができず、API修正に取り掛かりました(主に、実装がはるかに速いため、 APIを使用してクライアントごとにこの動作を実装する必要があります)。

どう思いますか?

2
Maxime Rossini

ユーザー入力を黙って変更しないことに同意します。混乱を招く可能性があり、エンドユーザーが送信したJSONデータを完全には反映しません。

クライアント側のユーザー入力の検証は回避できますが、URLが消費される前に変更されることをユーザーに示すことは賢明な手段です。

いずれの場合も、データ(この場合はURL)は整形式であると想定できるが、ユーザーはUIを完全に制御でき、誤ったデータを送信して厄介なサーバーエラーを発生させる可能性があるため、常に入力サーバー側を確認してください。 。

6
Ezgi Kaya

私には明らかな勝者がいます。

あなたは常に誰が何に責任があるのか​​自問するべきです。私にとって、Rest API(および任意のAPI)はシンプルに保つ必要があり、期待される以外の動作を決して追加しないでください。このシナリオでは、APIは、後で使用するためにデータを格納する役割を果たしますだから、いいえ、しないでください静かに修正してください

また、この責任をAPIに追加する場合、何を修正する必要があるか、何を修正しないかをどこで線引きしますか?

クライアント側で整合性が必要な場合は、この種の問題を管理するコンシューマーAPIにクラスを追加し、APIを使用するすべての場所でそれを再利用します。

4
barclow

言及されていないオプションが1つあります。それは、APIへの正しい入力を構成するものの定義を変更することです。 「facebook.com」を受け入れ可能なフィールド値にします(注:フィールドは現在[〜#〜]ではありません[〜#〜]URL))、そしてそれを文書化します。その場合、修正は必要ありません。 APIはこのフィールドを使用して、必要に応じて後続の応答を生成するときにハイパーリンクを作成します。これは、誕生日を使用してユーザーの年齢を計算するのと同じです。

私の見解の残りは、 Dan Wilson が書いたものに従います。

1
Nicholas Shanks

URL参照はよく知られているため、この特定のケースでは問題は発生しません。サービスは、facebook.com/foobarまたはhttps://www.facebook.com/foobarを有効な入力として受け入れることに問題はありません。

あなたはURLがFacebookページを参照していることを知っています。Facebookページは常にHTTPSを使用でき、wwwが指定されていない場合Facebookはリダイレクトを実行します。

ユーザー入力は変更しません。私は単に

  • uRLの形式と一致することを検証します
    • 検証のテストでのみ欠落しているスキームを追加して、本当に無効なデータ(facebook=com\foobar)を拒否できるようにする
  • ユーザーが提供したものをそのまま保存する
  • レンダリングするときに適切にフォーマットする(欠落しているhttps://を追加)

ユーザーが将来URLを変更する必要がある場合、ユーザーは入力した内容を正確に提示することができ、変更によって驚くことはありません。

データを変更することなく、ユーザーの期待に応えることができます。

1
Dan Wilson