不具合0でWEBツールをリプレイスできた取り組みの例
こんにちは、わさびです。ナビタイムジャパンでスポットデータの導入や運用基盤の開発を担当しています。
この記事では、スポットデータを管理するWEBアプリケーションのリプレイスを、不具合0でリリースした取り組みについてご紹介します。
ナビタイムジャパンでのスポットデータ
当社では、ナビゲーションサービスで目的地や出発地、経由地として選んでいただけるスポットデータを数多く収集、管理しています。
例えば、一時利用の駐車場データは10万件を超えており、常に情報を追加、更新することで、利用者が行きたいところへいつでも案内できるようにしています。
参考: 駐車場データを10万件以上、自社で集めた取り組みについて
スポットデータには、地点の名称や住所情報だけでなく、電話番号、ホームページのURL、営業時間、定休日、写真など数多くの項目が紐づいています。
スポットデータ編集のWEBアプリケーション
これらのデータは、様々なお店や企業の方と連携して収集していますが、一部の更新はスポットデータ編集WEBアプリケーションを使って手作業で修正しています。修正する数は1日あたり1000地点を超えますが、このツールがあることで、以前は直接データベースにSQLで整備していたスポットデータを簡単かつ大量に編集することを可能にしています。
ツールには、スポットの項目を1つずつ編集できる「スポットデータ編集画面」や、CSVファイルで複数スポットを一気に更新する「一括登録画面」など約20の画面で構成されており、機能も日々アップデートしながら運用しています。
リプレイスした背景
旧ツールのシステム構成は、オンプレサーバー上にAPIとしてPython、Django、WEBフロントのフレームワークとしてAnglerを採用し、スポット情報のデータベースへ登録する構成となっています。
いずれも最新版へのアップグレードとともに、オンプレサーバーからクラウドサーバーへの移行を主目的としてスタートしました。
また、将来の改修への懸念として、検証環境やテストコードがない一方、旧ツールのコードの可読性が低く、特に、Djangoのテンプレート機能によりフロントのコードがAPI内のコードに実装されていたり、デッドコードが肥大化していたりと、改修に膨大な工数がかかることが懸念されていました。
よって私たちは、リファクタという道ではなく、フルリプレイスの方針に舵を切りました。
リプレイスの方針
私たちがスポットデータ編集のWEBアプリケーションをリプレイスを進めるにあたり、重要視したのは以下の3点です。
間違ったレコードが追加されると、毎日の情報更新処理がストップするだけでなく、スポット名称が文字化けしたり、各アプリのコードで想定外のエラーを発生させる危険性があります。よって特に重視したのは、1 の項目でした。
一方、2、3について、当初は機能や処理の改善を行う方針でしたが、1との両立が取れなくなったため、リリース後に回し、必要な機能、処理のみを移植する方針に変わりました。
新ツールのシステム構成は、クラウドサーバー上に、APIとしてPython3、FastAPI、WEBフロントのフレームワークとして、Nuxt.jsを採用しました。
データベース操作の検証をどう担保したか
旧ツールの可読性が低いなか、当初は処理の改善を行いながら実装していたため、検証は手厚く行うことになりました。頼ったのは以下の3つです。
1. 単体テスト
2. APIテスト
3. シーケンステスト
新ツールでは、データベースを更新する処理に単体テストを実装し、期待するレコードチェックも入れながら、仕様をできるだけ担保するようにしました。
APIテストでは、リクエストとレスポンスが期待通りか担保し、単体テストとの責任範囲を分けています。
詳細については、別の記事で取り上げているので、こちらをご参照ください。
一方、シーケンステストでは、フロント側との結合動作確認や、複数画面で結果を共有する場合の確認を含めて実施しました。
単体テストでは関数レベルで期待する入出力の担保、APIテストではレスポンスの確認のみであったため、画面からファイルを入力した場合のデータベースの状態確認はこのフェーズで行いました。
具体的な手順としては、
という操作を自動化しながら進めました。
効果のあった取り組み
検証を手厚くする分、早期クローズに向け、次のような取り組みも行いました。
1. pytestの自動実行
単体テスト、APIテストはCIで実行し、すぐ結果を確認できるよう環境を整えました。これにより思わぬ部分への影響や、未コミットのコードの発見などがプルリク前やデプロイ前に確認しやすくなりました。
2. 複雑度測定
旧ツールの隠れた複雑な処理を早い段階で発見し、工数見積の参考や検証期間の確保に複雑度測定を取り入れました。
利用したのは、循環的複雑度の測定ができる lizard で、簡単に説明すると、forループの数やif文の分岐で値が高くなります。一般に、10以下が非常に良い構造のコード、75を超えるといかなる変更も誤修正を生むコードと言われています。
参考: github lizard https://github.com/terryyin/lizard
参考: 循環的複雑度 https://jp.mathworks.com/discovery/cyclomatic-complexity.html
リリースした今
リリースして1ヶ月程度経過しましたが、幸いなことに、リプレイス後の不具合はいまだ起きていません。またリプレイス後のコードでは、複雑度は15以下であり、今後の改修もしやすいものに変わったと思っています。
次のWEBツールのリプレイスがあるとすれば、言語のバージョンアップだけを先に行う、旧ツールのリファクタやテスト実装を先に行うなどでより早く開発が進められないか検討したいと思っています。
新しくなったスポットデータ編集WEBツールで、これからも鮮度の高い地点情報をお届けします。