バリデーションを再考する

僕は以前、 「DDDで考えるマイクロサービスのバリデーション」という大それた記事を書いた。

qiita.com

マイクロサービスっていうのが、ちょっと良くわかんない。

整理されてなくて、何が言いたいのかも良く分からないので、

再考した結果を、リライトしてみます。

リクエストパラメタの入力値検証

結論

値オブジェクトを作って、検証しよう。

詳細

プレゼンテーション層では、アプリケーションサービスの引数に渡す値だと考える。

ただ、値が妥当かどうかを判断するには、プリミティブな型だと情報が足りない。

それが、「メールアドレスとして欲しい」のか、「7桁の文字列が欲しい」のかStringじゃ分からない。

値オブジェクトを作って、validかどうか検証した結果、validならアプリケーションサービスに渡せばいいし、 駄目だったら、ユーザーにバリデーションエラーとして返す。

業務処理でのバリデーション

結論

  • 引数の値オブジェクトは検証済みが来る想定ですが、念の為DbC的にチェックして、invalidな場合は、例外で落としてもいい気がする
  • 例外を通知して、プレゼンテーション層側で、ユーザーに返せる形にする

詳細

入力値としては正しいが、業務上処理できない場合がある。

例えば、「登録済みのメールアドレスでユーザーを登録できない」がある。

この検証は、アプリケーションサービス中で行わないと、業務上、同じメールアドレスを持つユーザーを登録できても良いことになる。

検証に失敗したら、例外をスローして、プレゼンテーション側で、422として返すのか、500として返すのか振り分ける。

入力値がそもそも正しいかは、契約による設計(DbC)的にチェックして弾いちゃっていいかも。

インフラ層での検証

結論

テーブルの制約で頑張る

詳細

結論通り、テーブルの制約で頑張る。

正直、アプリケーションコードで頑張ってバリデーションしても、通り抜ける事はよくある。

チーム開発している大きなアプリケーションは、気付いた時にはトランザクション中で、重たい処理をしていて、メールアドレスが重複してユーザーが登録されたりしている。

メールアドレスにユニーク制約つけて、退会したらメールアドレスをランダムにマスクしたりして、強制的に変更しておく方が誤送信の防止とかにもなるし、安全なはず。