この記事はBASE Advent Calendar 2020 20日目の記事です。
こんにちは。BASE BANK 株式会社 Dev Division にて、 Software Developer をしている永野(@glassmonekey )です。
今回は先日リリースした「BASE」上での売上情報をCSVでダウンロードできる売上データダウンロードAppの裏話的な内容となります。
タイトルにTDDとつけたものの、そこまでTDDの話は出てきませんのでご了承ください。
BASE( ᐛ )⛺️ 新しい機能「売上データダウンロード App」が誕生しました〜!👶🎉
— BASE(ベイス) (@BASEec) 2020年11月18日
売上にまつわるデータをCSVにてダウンロードすることが可能💡
またサービス手数料や、決済手数料についても確認することができます👍
利益の分析にも使うことができるので、ぜひ使ってね💴https://t.co/WTM4bJlaei
売上データダウンロードAppについて
最初に今回の実装した機能の説明をします。
使い方のヘルプページに詳細は記載しておりますが、「BASE」上の売上やお金の動きをCSVでダウンロードできる機能です。
この機能の元々は、実験的に弊社のCSEチームが手動で明細を内部向けに出力していた機能でした。それを「BASE」の拡張機能としてリリースすることとなり開発の手はずとなりました。
CSEチームが普段どのような業務をしているかに関しては、弊社の小林(@sharakoba)が書いた社内業務改善を行うCSEグループのご紹介を御覧ください。
「BASE」は今年で8周年
少し話は変わりますが、先日弊社は今年で8周年を迎えました。ネットショップ作成サービス「BASE」は、BASE株式会社設立の1ヵ月ほど前にリリースされたので、サービスもリリースしてから8年の月日が経過しています。
【御礼】
— BASE, Inc. (@binc_jp) 2020年12月11日
BASE株式会社は創業8周年を迎えました https://t.co/UOuAWrES3G @binc_jpより
私自身は入社して半年ではありますが、これだけ長く愛されるサービスに関わることができてエンジニアとして感無量だったりします。
ただ、8年も経過するとサービスの内部仕様は当然変化しますし、データもローンチ当初とは色々異なる面がでてきます。
今回作ろうとしていた機能は、データベースの内容を集計して出力する機能なだけではありました。
しかし、過去のデータを加味すると現在のアプリケーションコードでは読み取れないデータの動きなどを想定する必要が出てくることとなり、それなりに難易度の高い機能だったわけです。
過去と戦うアプローチについて
では8年の過去と戦うにあたり事前に要件などをそろえることは容易でありませんでした。 今回役に立った観点は以下の3点でした。
- 生SQLを書く
- TDDを開発プロセスの軸とする
- 推測をせず計測をする
生SQLを書く
集計に必要なデータも複数テーブルに散らばっていたり、複雑な条件といった実情がありました。なので、処理的観点と可読性的観点で手続き的に書くことは現実的ではありませんでした。
そこで今回の実装においては、生SQLを書くことで実現させました。
また生SQLを使っていたおかげで、ソースコード上のSQLからGUIツールを使用して、実行計画の検証などが容易に行うことができた点は良かったと考えます。
別途SQLファイルをGit管理するなども検討はしましたがメンテナンス対象を増やしたくなく、SQLをソースコードの中のロジックとして一元管理することを選びました。結果として250行ほどのプロダクションコードで動く生SQLを生むことになってしまいました。
ただ、大規模なSQLのレビューをすることもしてもらうことも現実的ではありません。少なくとも私には難しい…
そこで、SQL文自体をレビューすることは半ば諦めて、レビュー時にテストコードや実行計画をつかって共有することでレビューの意図を伝えやすくする工夫をしました。
TDDを開発プロセスの軸とする
今回実装しようとした機能は、基本的なコア機能は集計処理なので、人間が目検で確認することはほぼ意味をなしません。
開発の初期段階では自分たちでデータを作ってチェックしていたのですが、何が正しいか判断がつきずらくあまりワークしませんでした。
そこで、テストデータには過去のデータベースのデータや、CSEチームが作成してくれた先行プロダクトの結果を採用しました。
これにより、我々開発者の手元でフィードバックループを回せるようになったので、より確度の高い開発を効率よく進めることができました。
また、前述の通りプロダクションコードの大部分がSQLを締める実装だったので、レビューも容易ではありませんでした。 テストコードが結果的にどのようなケースを担保するかを明記することになるので、レビュイー側としてはテストコードを見ればよくなります。 どのような意図でSQLを変更したのかのコミュニケーションができたことは良かったです。
ただ、テストのバリエーションに関しては、いたずらに増やしすぎたところもあるので今回の反省として開発に活かしていきたいですね。
推測をせず計測をする
また、データ量、バリエーションともに多い機能開発ではあったので事前に、「BASE」上のおおまかなデータ量の分布を算出してはいました。
そのため集計データ量の規模感やワーストケースは事前に把握をできてはいました。
今回の実装処理のボトルネックがデータベースレイヤーだったこともあるので、上記のSQLレイヤーの検証でその要点を押さえることができた点も大変意義のあるものでした。
これにより、我々が作ろうとしている処理の規模感とパフォーマンスを効率よく把握ができました。この点も手戻りの少なく開発できた要因でした。
現在はDBに記録された内容を元に、redashのダッシュボード上で可視化するようにしています。そこから継続的なパフォーマンス確認しています。
将来的には弊社で導入をすすめているNew Relicに寄せていけたらと思っています。
まとめ
今回は「BASE」上のアプリケーション開発における裏話をさせていただきました。
推測するな計測しろを地でいく開発ができたので、一部予想外な出来事はあったものの大きなハプニングもなく乗り切ることができてよかったという思いです。
今回、TDDというアプローチを取ったことで、エンジニア個人だと観測出来ない問題を手元で観測できるようになりました。その恩恵で、開発期間の中のバグ修正時に、大きな手戻りを引き起こすこともなく効率よく開発を進めることが出来たので実践してみて良かったです。
さらに、今回は大規模SQLをメインに据える選択をしましたが、テストコードのおかげで挙動に対する一定の理解を助けるツールにもなってくれました。レビューなどのチームとのコミュニケーション時に大変助けられました。
リリース後に嬉しい反響もありまして、これを励みに開発者としてこれからも頑張っていきます。
@BASEec の売上データダウンロード機能追加キター!欲しかった機能に歓喜。https://t.co/RmByzNDcO8
— センベイブラザーズの兄:(有)笠原製菓4代目 (@senbeibrothersA) 2020年11月18日
この機能欲しかったやつ! https://t.co/PXnPn28HJV
— 道草 michikusa (@warannahito) 2020年11月19日
昔は「BASEでいい」だったのが最近は「BASEがいい」になってる https://t.co/69azfxhkqi
— 陶 (@jamdxsp) 2020年11月19日
そのような開発を一緒にわいわいやっていく仲間を募集中です。 @glassmonekey へのDMなどでも気軽にご相談ください。
明日は BASE Data Strategyチームの氏原 (@beerbierbear)さんによるGNNレコメンドについてです!!
こうご期待!!