LaravelでSQL実行アプリを作る中で、要件理解の重要性を学んだ話
はじめに
新卒研修の一環で、チームで社内向けのSQL実行アプリケーションを開発しました。
- Laravel + クリーンアーキテクチャで実装
- TDDで開発(UnitTest / E2Eテストあり)
- SQLテンプレート管理、実行履歴、再実行などの機能を実装
開発自体は順調に進んでいたのですが、途中で前提となる要件が大きく変わるという経験をしました。
この記事では、そのときの設計変更と学びについてまとめます。
作ろうとしていたもの
最初に想定していたのは、SQLをWeb上から実行できるアプリケーションでした。
- SQLを実行できる
- 実行履歴を保存できる
- テンプレートとしてSQLを管理できる
- 過去のSQLを再実行できる
いわゆるSQLクライアントツールの簡易版のようなものをイメージしていました。
初期の設計
当初は、更新系SQLについて以下のようなフローも検討していました。
- BEGIN
- UPDATE
- SELECT(更新後の確認)
- ROLLBACK
一度ロールバックして、結果だけ確認するような設計です。
違和感と要件の再確認
開発を進める中で、
- なぜ履歴を残すのか
- どのように使われるのか
について改めて話す機会がありました。
既存の運用
実際の運用は以下のようなものでした。
- 踏み台経由で本番DBに接続
- SQLクライアントでSQLを実行
- 実行後にSlackへ以下を投稿
- 実行理由
- 実行したSQL
これは主に、障害発生時の原因追跡のためのログとして使われていました。
本当の目的
ここで認識が変わりました。
このアプリの目的は
「SQLを自由に実行すること」ではなく
「更新操作のログを確実に残すこと」
でした。
設計の見直し
SELECTは対象外
SELECTはデータを変更しないため、
- 障害の原因になりにくい
- ログとしての価値が低い
という理由から、実行対象から除外されました。
更新系SQLのみを対象にする
対象は以下に限定されました。
- INSERT
- UPDATE
- DELETE
副作用がある操作のみを扱う設計です。
トランザクションの扱い
初期に検討していた
- BEGIN / ROLLBACKで確認するフロー
についても議論がありましたが、
- アプリケーション側でトランザクション制御を行うのは難しい
- 接続方法や実行環境によって挙動が変わる
といった理由から、採用されませんでした。
最終的な形
最終的には以下のようなシンプルな構成になりました。
- SQLを実行
- 実行内容(SQL・理由・ユーザー)を保存
- 一覧・検索・再実行が可能
学び
要件理解が最も重要
最初は「SQL実行ツールを作る」と思っていましたが、
実際には「ログ管理の仕組みを作る」ことが目的でした。
目的を正しく理解しないと、設計は簡単にズレてしまうと実感しました。
技術的に正しいことが最適とは限らない
トランザクションを使った確認フローは技術的には正しいですが、
今回の目的には不要で、むしろ複雑さを増すものでした。
仕様変更は普通に起きる
新卒としては「ここまで作ったのに変わるのか」と感じましたが、
要件が明確になるにつれて仕様が変わるのは自然なことでした。
今振り返って思うこと
当時は要件を正しく理解できておらず、
「どう実装するか」に意識が向いていました。
今振り返ると、
- 目的の確認をもっと早い段階で行うべきだった
- ユーザーの運用を深く理解することが重要だった
と感じています。
Discussion