メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

API認証基盤の改善について

今月の一日でメドピアに入社してちょうど1年になったCTO室の内藤(@naitoh) です。

主にやっていることはAPI認証基盤の改善です。 この1年でやってきた事を技術ブログで紹介させて頂きます。

背景

メドピア で採用されているバックエンドの言語(フレームワーク)は本 blog のタイトルにもあるように PHP から Rails に移行が行われているのですが、 実は上記以外に Golang(以下 Go) も使用しています。

このあたりの当時の開発背景は下記の記事に書かれておりますのでご参考にして頂ければと思います。

tech.medpeer.co.jp

私が昨年入社した時点でこのAPI認証基盤(API ゲートウェイ)の保守が難しく、Go のわかる開発者がほぼいなかったため機能追加が行えない状態になっていました。 このAPI認証基盤へのユーザーログイン処理時のアクセス負荷が朝方に集中し、メドピアのサービスに影響が出ないか懸念されていたため、まず安心して保守できる状態に持っていく事から取り組み始めました。

安心して保守できる状態に持っていくためにやった事

  • 開発環境でコンパイルできるようにする。
  • CIが停止していたので、動くようにする。
  • テストコードを追加する。
  • テストコードを使って動作を理解する。エラーメッセージを修正する。
  • 未使用のライブラリを削除する。
  • 社内の非公開リポジトリ(ライブラリ)の2重管理を排除する。

開発環境でコンパイルできるようにする。

2015年の開発当時は Go 1.5 を使っていたため、入社時点で開発環境として支給された macOS Mojave ではコンパイルしたバイナリを実行すると実行バイナリの応答が無い状態になり、30分程待っても何も起らず正しくコンパイルできてない事が判明しました。(本番への deploy 環境は Linux なので問題なし。)

Go のコンパイラのバージョンを変えいくつか試したところ macOS 10.12 Sierra 以降では go 1.7以上必須 である事がわかったため、Go のバージョンを当時の最新の 1.13 まで上げ、かつ、struct 周りの記述ミスでコンパイルエラーが発生していたのを修正する事で開発環境のmacOS Mojaveで無事動作するようになりました。

CIが停止していたので、動くようにする。

2015年の開発当時は社内の Circle CI 1.0 (Enterprise) で CIが動作していたようなのですが、社内開発環境のクラウド移行時に、メンテナー不在の影響でクラウド環境のCircle CI 2.0 移行が行われずCIが停止していました。 Circle CI 1.0 当時の設定が残っていたので、Circle CI 2.0 で動作するように対応を行い、カバレッジ情報の出力を追加するなどCI環境を整備しました。

テストコードを追加する。

ある程度のテストコードは書かれていたのですが、メインロジック部分のテストコードが一部しか存在しなかったため、処理を理解するためテストコードのカバレッジを上げる事に取り組みました。 ただ、期待値となるドキュメントの場所がわからず、社内メンバから教えてもらった内容も記述が2015年のまま古い箇所が散見されたため、本当にこれが当時の情報なの?と恐る恐るテストコードを書きながら正常系のテストコードを書き上げました。(結果的に正しい情報でした。)

テストコードを使って動作を理解する。エラーメッセージを修正する。

エラー発生時のエラーコードが毎回同じ値を返したり、エラーメッセージが同じ箇所が複数あったり詳細エラーメッセージが出力されないバグがあった事が原因で、どこでエラーが発生したかソースコードを見ても判断ができず、クライアント側も最初の処理からリトライせざるを得ないなど利用者にわかりづらいAPIとなっていました。

そのため、異常系のテストコードを追加し、詳細エラーメッセージが正しく出力されるように修正、エラー時の挙動を理解することで、本来意図している内容にエラーメッセージの修正を行い合わせてエラーコードの整備など使い勝手の改善を行いました。

未使用のライブラリを削除する。

2015年の開発当時に組み込まれた未使用のライブラリがそのままになっており、(vendor 配下のリポジトリにはあったのですが)元のリポジトリが残っていないものもありました。 削除してテストが通る事を確認し、メンテナンス対象を整理しました。

社内の非公開リポジトリ(ライブラリ)の2重管理を排除する。

上記 vendor 配下の整理を行なったのですが、社内開発ライブラリ(非公開リポジトリで別管理)もvendor配下に登録されていたため2重管理になっており、両方のソースコードに修正が入るような状態になっていました。(glide で 管理は行われていたのですが、Go 1.5 で vendoring が始まったばかりで当時はこのように管理するようにしたようです。)

社内ライブラリは vendoring 不要なため vendor配下での 2重管理を廃止し、Circle CIで glide がうまく動作しなかったため(Go 1.13 では正式版ではなかったため Go Module への移行は見送り) dep に移行し、コンパイル時に dep ensure で社内ライブラリをvendor配下に展開する対処を行いました。

安心して保守できる状態に持っていくためにやった事のまとめ

これらの対処により約4ヶ月ほどでメンテナンスが可能な状態に改善、無事リリースする事ができました。 懸念となっていた朝のログイン時の負荷問題は不要なToken再発行処理である事が判明し、別途行われたクライアント側の改修作業で無事問題は解消されました。

現在は次のステップとしてAPI認証基盤がもっと活用されるようにする取り組みを行なっています。

現在の取り組み

上記対処を実施するまでAPI認証基盤の機能追加ができなかったためか、メドピアの各サービスはサービス単位に機能を作成する事が多く、各サービス間の連携が弱いという課題がありました。

また、メンテナンスが行える状態になったのですが、利用を広げるにあたり下記の課題がありました。

  • API開発をGoで行う必要があり、社内の Rails 開発者にとって敷居が高い。
  • JSON RPC API ゲートウェイ として実装されていたため一般的な REST APIではなく利用がしづらい。

これを解決するために、APIゲートウェイのバックエンドを Go ではなく Rails での実装を追加、新規にREST API のサポートを行なう事でこの課題を解消し、各サービス間の連携を強化する新APIの追加を行なっています。

f:id:ju-na:20201109163946p:plain
API Gateway

(API ゲートウェイそのものは負荷が集中する部分で、機能追加が少ない部分のため、Go での実装を継続しています。)

おわりに

以上のような施策を実施し、社内サービスのボトルネックを一つずつ改善していく取り組みを行なっています。

前職は組み込み系のテストプログラム開発を行なっていたため Go は触った事がなかったのですが、Go は言語仕様が比較的小さいため2週間程の勉強は必要でしたが無事改善が回せております。 開発分野が前職とはだいぶ異なるため新たに学ぶ事が多いですが、(Goに限らず)日々新しい事に取り組みつつ楽しく開発をしております。


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html