【インターンレポート】LINEのAPIのアクセス制御改善とプロダクション環境へのデプロイを行いました

こんにちは。LINEの冬インターンシップのサーバサイドコースに参加した佐藤佑飛です。
インターンシップでは開発4センターのDP2チームに所属し、実際の開発プロセスを経験しながら、LINE(コミュニケーションアプリ)のバックエンドで動作するAPIの機能改善に取り組みました。そしてなんと、開発した機能をプロダクション環境にデプロイすることができました!

本記事では、その取り組んだ内容について紹介します。

テーマ:友だち関係を操作するAPIを改善

私が取り組んだのは、LINEの友だち関係を操作するためのAPIに対して、より細かなアクセス制御を導入するというタスクです。
LINEのサーバサイドはマイクロサービス化されていて、WebAPIなどのRPCを通じて全体のサービスが構築されています。
その一部として、LINE公式アカウントやBOTとの友だち関係を操作するためのサービスがあります。
従来のアクセス権管理方式では、あるアカウントはそのサービスが提供する全てのAPIにアクセスできるorできないの2通りで、特定のAPIだけを許可することはできませんでした。
これから様々なAPIが追加されることを考慮すると、APIごとにアクセスを制御できたほうが好ましく、改善が求められていました。

インターンシップ期間中に取り組む内容はメンターの方と相談しながら決めたのですが、実際のサーバサイドの業務を体験したい&LINEのプロダクトに手を加えたいという相当にわがままなお願いを受け入れてくださり、このタスクを担当することになりました!
上手くいけばプロダクション環境にデプロイできるということで、非常に高いモチベーションでタスクに取り掛かることができました。

開発プロセスを体験

開発にあたっては、設計、実装、テスト、レビュー、デプロイなど、実際の業務と同様のプロセスを体験することができました。
それぞれのプロセスでやったことを簡単に紹介したいと思います。

設計

設計では、アクセス制御の実装方式やアクセス権限を設定する設定ファイルの仕様について時間をかけて検討しました。また、この実装方式が実現可能かどうかなどの技術的課題に対する調査もこの段階で行いました。
設計に正解はありませんが、適切な設計というのは存在し、それは何を観点とするかによって決まります。
そのため、検討事項について複数の観点から見たときの利点・欠点をまとめた資料を作成し、それをもとにチームの方々と議論して設計を進めました。
アクセス制御の実装方式については、リクエストに対してどのレイヤーでアクセス権をチェックするかを検討しました。

最も簡単な方法は既存の実装を拡張することでしたが、今回はAPIの拡張性などを重視して、別の方法で実装することにしました。
設定ファイルは仕様を頻繁に変更する訳にはいかないので、とくに議論を重ねました。
設定ファイルは人が手作業で書き換えるため、オペレーションミスが生じる可能性があります。
そのため、設定を簡潔に記述できることや既存の仕様を改変しすぎないことなどに留意して設計しました。

結果として、いい感じの仕様になったと思っています!
個人で開発をしているときは深く考えずに設計を終えることが多いので、じっくりと設計を考えるというのは良い経験になりました。
チームの方々のように、知識と経験にもとづいてベターな設計を選択できるようなエンジニアを目指して精進したいと思います!

実装

開発したプロジェクトはJavaで書かれていて、RPCサーバとして⾃社製OSSの[Armeria]を使⽤しています。
そして、プロジェクトは⼀貫してノンブロッキングな構成になっています。
設定ファイルに対するアクセスもブロッキングしないようになっており、設定ファイルに変更があったときは、その変更が通知され、⾮同期に設定を反映できるような仕組みになっています。

他にもJavaでWeb開発をするための様々な技術が使われているのですが、はじめて触る技術が多く、勉強しながらトライアンドエラーする⽇々という感じでした。
リクエストに対してアクセス権をチェックする処理はSpring AOPにより実装しました。
Spring AOPは、Springでアスペクト指向プログラミング(AOP)するための技術で、実装に対して後から横断的に処理を追加することができます。
実装の関心事を分離することができるため、凝集度と結合度の両面に優れた実装を実現可能です。

今回の実装では、APIの定義となるメソッドに対して、アクセス制御の処理を挿入するようにしました。
そして、ここからは実装で苦労した話になります。
このようなAOPの処理は、アスペクト対象のクラスをプロキシ化したオブジェクトをプログラム実行時に生成することで実現されています。
一方、プロジェクトで使用していたバージョンのArmeriaは、プロキシ化されたオブジェクトに含まれるメソッドにURLをマッピングできないという問題を抱えていました。
最新のバージョンではその問題が解決されていそうだったのでArmeriaをアップデートしたのですが、今度はこれまで動いていた部分が動かなくなってしまいました!
ArmeriaやSpringの中身を追いかけたり、チームの方々に助けていただいたりしながら、なんとか実装を終えました。

テストも書いた

実装と並行してテストも書きました。
テストでは幸運にも(?)、ローカルではパスできるが、Jenkinsではパスできないという現象に遭遇しました。
原因はリフレクションの実装が実行環境に依存していたことだったのですが、この一件のおかげでテストを書くことの重要性を、身をもって体感することができました。

20件を超えるレビュー

チームの方々から熱いレビューをいただきました!
画像は私のPull Requestに対するコメント件数です。

プロのエンジニアはどう実装するのかを知ることができ、とても勉強になりました。
テストで怪しい挙動を示したリフレクションは綺麗サッパリなくなって、シンプルで素敵なコードになりました。

そしてプロダクション環境へ

テスト環境へのデプロイを経て、いよいよプロダクション環境へのデプロイです。
デプロイの瞬間はやはり緊張しましたが、レビューでとても丁寧に目を通していただけたので、自信を持ってデプロイすることができました!

まとめ

本記事では、インターンシップで取り組んだ内容を紹介させていただきました。
非常に濃密な4週間で、設計からデプロイまでの開発プロセスをLINEで体験することができたのは最高の経験になりました。
インターンシップ期間中には、技術的な会議のほかにマーケティングの会議へ参加する機会にも恵まれ、企業としての成長とプロダクト開発の関係について学ぶことができました。業務以外では、社員の方々やインターン生の同期と交流する機会を設けていただきました。
いろいろなお話を聞くことができ、技術面以外にも本当にたくさんのことを勉強することができました。LINEのインターンシップはとてもオススメなので、興味がある方はぜひエントリーしてみてください!

Related Post