REST APIを実装しており、CREATEおよびUPDATEエンドポイントのJSON API入力を検証する必要があります。入力が無効な場合は、処理を実行する前に400エラーを送信することが目標です。
過去には、ほとんどの人と同様に、Marshmallow/Cerberus/Schema/Voluptuous/Schematicsなどのスキーマ検証ツールを使用しています(ここではPythonを使用しています)
しかし、私のDBモデル自体に、データベース内のデータの一貫性を保証するためのバリデーターや制約を含めることができます(すべきですか?)。
それを念頭に置いて、レコード作成の私の一般的な戦略は次のようになります。
create_record(inputs):
errors = validate_schema(inputs)
if errors:
send_400(errors)
try:
record = create_record(inputs)
catch:
send_500()
return record
だから私はいくつかの潜在的な欠点がある2つの場所である種のデータ検証を実行する必要があるように思えます:
これに推奨されるいくつかのDRY戦略はありますか?
構文的に正しい(ここではHTTP 400
は誤解を招く)ために400
を使用しないことをお勧めしますが、意味的に正しくない(別名invalid)リクエストです。しかし、それはここでのトピックではありません。
問題は、検証と[〜#〜] dry [〜#〜]についてです。
私は、ここに従うべき黄金律はないと思います。最新のWebアプリケーションを実行している場合、二重簿記[〜#〜] dry [〜#〜]と保守性の間にはトレードオフがあります。
典型的なスタックは:
そしてあなたのケースでは、あなたのコードとあなたのDBに検証があります。
使いやすさのために-ユーザーの観点から-クライアントに検証レイヤーを用意し、対話的にエラーを示し、入力を改善する方法についてアドバイスを提供することは理にかなっています。エラーが発生したため、Form
に記入してサーバーに送信し、すべてを再入力する必要があった時代は終わりました。
とはいえ、クライアントとサーバーの間には常に-少なくともある種の-二重の簿記があります。 ビジネスロジックを1か所に保ち、コードジェネレーターを使用してクライアント側とサーバー側のコードを生成し、防止する[ 〜#〜] dry [〜#〜]少なくとも論理的な観点から。これは、ソフトウェアを維持するのが難しく、地獄に終わりました。
バックエンドで[〜#〜] dry [〜#〜]についての質問に来ます。検証ロジックを2つの部分に分割することには意味があります。
1)データベースが最もうまく処理できるもの:
2)コードが最も得意とすること:
これにより、データアクセス層から発生するエラーのクラスがおよそ2つになります。
後者はvalidation error
に変換されます。
datatypes
の場合、ある種の二重チェックが発生します。何かが日付かどうか-それは無視できるでしょう。そして、残りは直交/比較的DRYです。
[〜#〜] but [〜#〜]:一貫性要件に依存しますデータベースを一種の最後の防御線データベースだけでなくコードにも検証ロジックを実装します(これにより、[〜#〜] dry [〜#〜])。
ドライな方法は、存在する可能性のある検証エラーの種類ごとに検証を行うのではなく、create_record
からの複数の種類のエラーを処理することです。例えば
try:
record = create_record(inputs)
catch InputsValidationError:
send_400()
catch:
send_500()