【マイレース開発記録(8)】
バリデーション地獄
入力チェックって、思ったより大事だった
前回は、Flask APIを使って、
画面から情報を送る
↓
サーバーで計算する
↓
結果を返す
という仕組みを作りました。
ここまで来ると、
「これでレースを動かせる!」
と、ちょっと嬉しくなります。
ところが、実際に動かしてみると、
また新しい問題が出てきました。
それが、
「もし、変なデータが送られてきたらどうなるんだろう?」
ということでした。
そこで必要になったのが、
バリデーション(入力チェック)です。
これが思っていた以上に、奥が深かったんです。
マイレースには、いくつかの入力がある
マイレースでは、主に次の情報を入力します。
- 生年月日
- 出生時間
- 出生地(都道府県)
- 眺めたい日(占いたい日)
これらの情報を使って、
天体の位置などを計算していきます。
つまり、入力された情報が正しくないと、
その後の計算も正しくできません。
例えば、
- 生年月日が入力されていない
- 出生時間が入力されていない
- 都道府県が選ばれていない
- 生年月日より前の日を選んでいる
といったことが起こる可能性があります。
「ちゃんと入力してね」
だけでは、アプリは守ってくれません。
ここで初めて、
入力されるデータは、
最初から正しいとは限らない
ということを意識するようになりました。
「requiredがあるから大丈夫」ではなかった
最初は、
必須項目にしているし、
これなら大丈夫かな?
くらいに考えていました。
でも、Webアプリの場合、
画面から普通に入力されたデータだけが来るとは限りません。
APIには、画面を経由せずに
直接データを送ることもできます。
つまり、
画面側でチェックするだけでは十分ではない
ということです。
そこで、
- 画面でもチェックする
- サーバーでもチェックする
という考え方が必要になりました。
ここでようやく、
バリデーションは、もしものための保険ではなく、
アプリを支える大切な部分なんだ
と気づきました。
Flask側でチェックすることにした
そこで、API側では、
- 入力されたデータを確認する
- 正しい形式かチェックする
- 内容に矛盾がないか確認する
- 問題があればエラーを返す
という流れにしました。
例えば、
「出生地が存在しない」という場合には、
出生地が不正です
と伝えます。
また、
「生年月日より前の日を占いたい日として指定している」場合には、
占いたい日は出生日以降にしてください
と伝えます。
単に、
エラーが発生しました
とするのではなく、
「どこを直せばいいのか」が分かるメッセージに
することを意識しました。
ところが、チェック項目が増えていく
最初は、
「入力を確認するだけだから、そんなに難しくないだろう」
と思っていました。
ところが、実際に考えてみると、
- 日付として読み取れる?
- 時刻の形式は正しい?
- 出生地は存在する?
- 日付同士の関係はおかしくない?
- 空欄だったらどうする?
- 想定外のデータが来たら?
と、次々に考えることが出てきます。
さらに、
- このチェックは画面側でするのか?
- それともAPI側でするのか?
という問題もあります。
ひとつ確認すると、また次の確認が必要になる。
そんな感じでした。
「チェックする順番」も大切だった
バリデーションを作っていて、
意外と難しかったのがチェックする順番です。
例えば、日付が空なのに、
「この日付は正しいかな?」と先に調べようとすると、
その前の段階でエラーになってしまいます。
そこで、
まず形式を確認する
↓
次に内容を確認する
というように、順番を整理していきました。
例えば、
- ① 形式を確認する
「これは日付として読み取れる?」 - ② 存在を確認する
「この都道府県は登録されている?」 - ③ 内容を確認する
「生年月日より前の日を指定していない?」
というように、
少しずつ段階を分けて考えることにしました。
こうすると、何が原因なのかも分かりやすくなります。
私にとっては、条件を整理することが難しかった
バリデーションは、細かい条件がたくさん出てきます。
- 「Aならこうする」
- 「Bならこうする」
- 「この場合だけ例外」
というように、一つずつ考えていく必要があります。
私の場合、こうした条件が増えてくると、
「今は何を確認しているんだっけ?」
となってしまうことがあります。
ひとつの問題を直しているうちに、
別の条件が気になってしまう。
そして、気づいたら全体が分からなくなる。
これが今回、かなり苦労したところでした。
そこで、AIに整理を手伝ってもらった
ここでもAIとの対話が役に立ちました。
私は、
- どんな入力ミスが考えられる?
- どの順番でチェックしたらいい?
- 形式チェックと内容チェックを分けられる?
- どんなエラーメッセージなら分かりやすい?
といったことを、一つずつAIに相談しました。
すると、
「チェック項目を一度、表にして整理してみましょう」
という考え方が出てきました。
そこで、
| 種類 | 確認すること |
|---|---|
| 形式チェック | 日付や時刻として読み取れるか |
| 存在チェック | 都道府県などが登録されているか |
| 論理チェック | 日付同士の関係がおかしくないか |
というように整理してみました。
頭の中だけで考えていたときよりも、
ずっと分かりやすくなりました。
バリデーションは、ユーザーだけのためじゃなかった
今回、特に印象に残ったのは、
入力チェックは、ユーザーのためだけではない
ということです。
もちろん、
「どこを直せばいいのか分かる」
という意味では、ユーザーにとって大切です。
でも、それだけではありません。
入力がある程度整理されていれば、
- バグの原因を探しやすい
- 計算ロジックの問題と切り分けやすい
- エラーの場所が分かりやすい
- APIの動きを安定させやすい
というメリットがあります。
つまり、
入口をきれいにしておくと、
その先の開発も楽になる
ということでした。
「動けばOK」から、少しずつ変わってきた
この頃から、私の中でも少し考え方が変わってきました。
最初は、
「とりあえず動けばいい」
という気持ちが強かったと思います。
でも、実際にアプリを作っていくと、
「普通に動く」だけでは足りないことが分かってきます。
間違った入力が来たときにも、
できるだけ分かりやすく対応する。
予想していなかったデータが来ても、
できるだけ安全に止める。
そういうところまで考えて、
少しずつ「アプリらしく」なっていくんですね。
AIとの開発で、またひとつ気づいたこと
今回も、AIに全部作ってもらうというより、
「自分の頭の中を整理する相手」として
使うことが多かったです。
- 「こういう場合はどうなる?」
- 「この順番でチェックしていい?」
- 「このエラーは、どう説明すれば分かりやすい?」
そんなふうに話していくと、
自分では気づいていなかった抜けが見えてきます。
一人で考えていると、
同じところをぐるぐる考えてしまうことがあります。
そんなときに、AIとの会話で一度外に出してみる。
それだけでも、かなり整理しやすくなりました。
今回の開発で感じたこと
バリデーションは、見た目にはあまり派手ではありません。
レースが速くなったわけでもないし、
新しい画面が増えたわけでもありません。
でも、
「ちゃんと動くアプリ」にするためには、
とても大切な部分でした。
そして、
一度に全部を完璧にしようとしなくてもいい。
ひとつずつ条件を整理していけばいい。
ということも学びました。
最初は「バリデーション地獄だ……」と思っていましたが、
振り返ってみると、
アプリの土台を少し強くできた工程だったと思います。
次回予告
次は、また少し違った問題が出てきます。
マイレースでは、
生まれた場所も天体計算に関係します。
そこで必要になったのが、
47都道府県の緯度・経度データでした。
ただ都道府県の名前を登録すればいい、
という話ではありません。
どの場所を基準にするのか、
データをどう管理するのか。
ここでも、また少しずつ考えることになりました。
次回は、
「出生地」をどう扱うかで設計が揺れた話を書きます。
また、試行錯誤の続きを残していきたいと思います。



