バリデーションという言葉とスマートな実装

Ken published on
5 min, 861 words

Categories: Programming

バリデーションをわかりやすく実装するって難しいって話。 頭の中を整理するために書いているので、まとまってない状態。

基本的なお話

ログイン時にIDとパスワードをポストするけど、受け取った側としてはその値が正しいかどうかを判断する。 この "正しいかどうかを判断する" ってのがやっかい。 IDとして正しいかどうか?というのは、

  • 英数字だけか?
  • 8文字以上か?

のような感じではあるが、これって 値が存在する前提の話 なんだよね。 まずは値が存在しているのかどうか?ってところから判断して、存在しない場合は正しいかどうかって判断できない。 だから、

  • 値が存在するか?

ってのも確認しなければならない。

悩み

どうやって実装したら綺麗なのか?

if id, ok := param("id"); ok {
  id.validation(required, max(8))
}

これでもいいんだけど、前提条件が揃っているか(パスワードが送られてきているか)を確認してから処理に移りたいよねって思う。

if (required("id", "password")) {
  id := param("id")
  pw := param("password")
}

そうなるとこんな感じかな?

だけど、他にもIDを保存しておくか?的なオプションがあって、keepidなんて項目まであったとする。

if (required("id", "password")) {
  id := param("id")
  pw := param("password")
  if keep, ok := param("keep"); ok && len(keep) != 0 {
    // IDを覚えておく処理
  }
}

なんてのはすっきりしないなぁ…と。 だいたい、値が送られて来なくても、値が空文字列であっても『IDは必要だよ』って旨は表示するわけだし、この辺が実装と現実の乖離。

さらに 値がない場合は初期値としてこれを使いたい みたいな場合は厄介事が増えてしまう。

こういうを考えているとScalaのOptionとmatchの表現はすっきりでいいなぁ…と思えてしまう。

こういうときはGoではどう書けばすっきりするんだ?

まとめ

値の存在確認もバリデーションって言葉で片付けられることあるけど、その言葉には依存関係が存在することもあって、スマートな解決を求める場合は一言で表さない方がいいのでは?と思ったりした。 今回の場合は、

  • 存在確認
  • 各種バリデーション

なのかな?と。全部まとめてバリデーションって表現もいいけど、実装上はこの差を明確にしておいた方がわかりやすいんじゃないかなと思った。 だけど、必ず存在していないと困るか?というとそういう項目ばかりではなくて…。

フレームワークって色々とやってくれるから便利ってのはもちろんのこと、この辺をあまり悩まなくて済むというのも大きなメリットだよな、と思ったのであった。

# コードハイライトの指定に "Go" がなくて "Python" にしちゃったよ。