APIをC#からGoにリプレイスをした話
はじめに
こんにちは、株式会社Mediiの渡辺です。
弊社が提供する「Medii Eコンサル」は、2020年のローンチ以来、医師を支援するサービスとして順調に成長を続けています。
その成長を支える一方で、サービスの裏側には技術的な課題も積み重なっていました。これに向き合い、2022年後半から2024年初頭にかけて、システム全体のリプレイスに取り組みました。
今回は、その中でも重要な取り組みの一つ、 APIサーバーのリプレイス についてお話しします。
リプレイスに至った背景
一言で言えば、「技術負債が無視できないレベルになったから」です。
創業当初、限られたリソースの中でサービスを早くローンチするために、とにかく「動くものを早く作る」ことを重視しました。その結果、サービスは無事にリリースされ、順調に成長を続けました。
しかし、後回しにしてきた技術的な課題が徐々に重くのしかかり始めました。
- 開発速度が落ち、思うように新機能がリリースできない。
- サポート切れのライブラリが増え、将来的なリスクが拡大。
- 技術的な負債が、エンジニアのモチベーションにも影響。
「このままではサービスの成長に支障が出る」と判断し、思い切った技術負債の返済に取り組みました。
リプレイス前後の構成
今回のリプレイスでは、APIサーバーを C#/EC2 から Go/ECS へ移行しました。
当時の課題とリプレイス理由
リプレイス前の課題
課題は多岐にわたりましたが、特に次の3点が大きな問題でした。
1. 採用技術
- C#エンジニアの確保が難しい: 比較的大手が多く、採用競争も厳しい。
- Visual Studio依存: 特にMac版が廃止され、開発環境の選択肢が限られる。
- .Netのアップデート対応が辛い: サポート切れリスクが高まる。
2. コード品質
- テストが一切書かれていない: 品質を担保する手段がなく、変更がリスクに。
- 重複や不要なコードの残骸: 開発速度を優先する中で蓄積。
- 複雑化した条件分岐: 設計の一貫性が失われ、保守性が低下。
3. Opsの未整備
- CI/CD環境が未整備: デプロイ作業に時間がかかり、人為的なエラーのリスクも。
- ローカル環境構築が困難: 環境準備に1日かかることも。
今の構成にした理由
Goを選んだ理由
- 後方互換性: 安定したエコシステムがあり、保守が容易。
- シンプルな構文: エンジニア間でコードスタイルが揃いやすい。
- 標準機能の充実: ライブラリを多用せずにAPIサーバーを構築可能。
- 採用競争力: Goを扱える/経験したいエンジニアが増えている。
- 社内の経験: 別プロダクトでの採用実績があり、ノウハウを活用。
ECS (Fargate) を選んだ理由
- コンテナ化前提: Dockerベースで開発環境を統一。
- Opsの効率化: 特にデプロイフローを簡略化。
- 社内の経験: 他プロジェクトでの利用実績があり、スムーズに導入可能。
リプレイスの実施
リプレイス後の構成は決定しました。
お次は実際にリプレイスをどのように進めていくかです。
基本方針
方針 | 理由 |
---|---|
ビッグバンリリースはしない | 100以上のAPIがあり、一括で差し替えるのはリスクが大きい また、追いかけ開発も必要となってしまう |
機能開発は凍結しない、 もしくは最小限に抑える |
●ヶ月開発止めます!ではビジネス側、PdMの理解を得られない |
テストコードは必須 | コード品質担保 後からテストは書かれることはないので、今このタイミングで書く |
APIの振る舞いは変えない | フロント側を修正最小限にするため 新旧APIで結果を比較し、期待値を明確化できる |
実際に行ったこと
テストコードだったり、APIの振る舞いを変えないのは、コーディング時にルールとしておけば実現できることです。
問題となるのはビッグバンリリースを避けることと、機能開発を凍結しないことです。
これに対応するため、ALBのパスベースルーティングを使い、新旧環境が共存できるようにインフラを整備しました。
本記事ではALBによるパスベースルーティングの詳細は割愛しますが、AWSのドキュメントに書いてある通りの方法です。
AWSのドキュメント
この構成により、リプレイス過渡期は2つのサーバが共存します。
APIの振る舞いは変えていないので、何らか問題が発生しても該当のルーティングを戻すだけでロールバックできます。
これだけでも精神的にかなり楽になります。
また、今後の機能開発に関連するAPIは優先的にリプレイスし、リプレイス後のAPIを修正する、もしくは最初からGoで新規APIを作成することで、機能開発を完全に止めることなく、リプレイスを進めることができます。
結果として、完全に機能開発を止めたのはリプレイスAPIの初回リリース前の2週間程度でした。
リプレイス期間
計画開始から完了まで約1年半かかりました。
- 2022年8月: 計画開始。
- 2023年3月: 初回のリプレイスAPIをリリース。
- 2024年1月: 全てのAPIのリプレイスが完了。
段階的リリースにより、軽微なバグはありましたが、大きなトラブルなく進められました。
振り返り
リプレイスは 技術負債を返済する手段であると同時に、リスクのあるプロジェクト です。
そのリスクを軽減するため、以下の方針を守ったことが成功につながったと考えています。
- 段階的なリリース によるリスク分散。
- テストコードの徹底 による品質の確保。
- ビジネス側との適切な調整。
おわりに
今回はAPIサーバーをC#/EC2からGo/ECSにリプレイスをした経験を書きました。
書き出してみるとスムーズに進んだように見えますが、実際は多くの試行錯誤と調整が必要でした。
実は同時並行でフロントエンドもVueからReactへのリプレイスをやりきっているので、この取り組みについても、また記事にしたいと思います!
Discussion