LINEヤフー Tech Blog

LINEヤフー株式会社のサービスを支える、技術・開発文化を発信しています。

【インターンレポート】LINE ミニアプリの URL に独自ドメインを導入するサーバサイド開発

はじめに

こんにちは。東京大学大学院情報理工学系研究科修士1年の櫻井晴基です。8月7日から6週間、LINE(現 LINEヤフー)の就業型インターンシップに参加させていただきました。

自分が配属されたのはDP2チームで、LINE Developer Productと呼ばれる、社内外の開発者がLINEアプリを中心としたLINEのエコシステムを、プラットフォームとして利用できるようなプロダクトのサーバーサイド開発を行なっているチームです。

本記事では、自分がLINEのインターンシップになぜ参加したのかを踏まえながら、実際に業務でやったこと、それを通じて学んだことや感じたことを書いていきたいと思います。

インターンシップの参加動機

私がLINEのインターンシップに参加したいと思った理由は大きく分けて2つありました。

まず1つ目は、大規模アプリケーション開発の現場を実際に見てみたいと思ったからです。ここでの「大規模アプリケーション」とは、ユーザー数という意味でも、コード量という意味でも大規模なアプリケーションを指します。これまでいくつかの会社でインターンを経験し、Webアプリケーションのサーバーサイド開発の基礎を学んできましたが、これまで関わってきたプロジェクトは、規模としてはあまり大きくないアプリケーションが中心でした。そこで、LINEアプリとそのプラットフォームの開発の現場で、技術的な面はもちろんのこと開発の進め方なども含めて経験や知識を得ることで、より広範で深い技術力を身につけたいと思いました。

2つ目の理由としては、「エンジニア」にはどのような仕事があるのかを、業務を通じて知りたかったからです。エンジニアのキャリアの進め方として、どのようなものがあるのかを、実際のエンジニアの方の業務を見学させていただくことで、自分がどのようなエンジニアになりたいのか、またそのために何を学び、どのようなスキルを磨いていくべきなのかを考える良い機会になると思いました。

実際にインターンシップで取り組んだこと

私がインターンシップで主に取り組んだタスクは、LINEミニアプリに独自ドメインを導入するというものでした。

LIFF・LINEミニアプリとは

DP2チームで開発しているプロダクトの1つにLIFF (LINE Front-end Framework)というものがあります。これはLINEが提供するWebアプリのプラットフォームで、LIFFを使うことで、LINEのユーザーIDなどをLINEプラットフォームから取得することができ、その情報を活用したアプリケーションを開発することができます。公開されているLIFF SDKを用いて誰でもオリジナルのLIFFアプリを開発できるほか、LINE NEWSなどの多くの社内プロダクトでも使われており、LINEアプリの中では欠かすことのできない基盤のプロダクトとなっています。

LINEミニアプリはLIFFアプリのプレミアム版のようなもので、ミニアプリ専用の利用履歴一覧画面があるなど、特別な機能を保有しています。LINEプラットフォームを活用して、モバイルオーダーやデジタル会員証などのシステムを構築することが可能です。

背景と目的

LINEミニアプリはLIFFを活用して作られているため、アプリにアクセスするためのURLは https://liff.line.me/{liff_id} という形式をとっていました。ここでの liff_id はLIFFアプリを一意に特定するためのものであり、10桁のchannel IDと8桁の文字列によって構成されます。しかし、これにはいくつかの問題点があります。

  • URLからだけでは、それが通常のLIFFアプリなのか、LINEミニアプリなのかを判別することができない
  • liff_id からはそのアプリがどのようなサービスなのかを知ることができない

これらの問題を解決するため、より直感的でユーザーフレンドリーなURLスキームの導入が求められていました。具体的には、それがミニアプリであることを明確に表し、同時にそのアプリが提供するサービス内容をユーザーが理解しやすい形で表現することが目的でした。

アプローチ

そこで、今回新たに miniapp.line.me というドメインを導入し、これによってミニアプリにアクセスすることができるようにしました。

具体的には、これまでの liff_id によって、  https://miniapp.line.me/{liff_id} とアクセスできるのに加えて、アプリごとにユニークな mini_app_id を指定でき、 https://miniapp.line.me/{mini_app_id} によるアクセスを可能にしました。

例えば、自分がLINEミニアプリを作って、 mini_app_id  sakurai と設定すれば、 https://miniapp.line.me/sakurai によって、アプリにアクセスすることができます。

この変更によって、

  • URLの可読性、視認性が高まる
  • ドメインからLINEミニアプリというものをユーザーに知ってもらえる

などの利点があります。

設計と実装

今回の機能を実現する上で、サーバー側での作業内容としては以下のようなものがありました。

  • DB設計 (MySQL)
    • mini_app_id カラムの追加と変更履歴テーブルの追加 (後述)
  • プロキシの設定 (Nginx)
    • ミニアプリ用のドメインを追加する
      • リクエストを判別して適切なエンドポイントに転送する
  • エンドポイントの実装 (Kotlin + Spring Boot)
    • 指定された mini_app_id を用いて、ミニアプリの情報を返す
    • アプリの作成、修正エンドポイントで、 mini_app_id の設定、修正を可能にする

以下工夫した点について、書いていけたらと思います。

工夫した点

DB設計における工夫

現状のLIFFサーバーにはLIFFアプリを管理するメインテーブルが存在します。今回の修正で mini_app_id の情報をデータベース上に追加する必要がありますが、いくつかの設計案を考え、最終的には、メインテーブルにmini_app_idカラムを追加し、別テーブルで変更履歴を管理するという設計を選択しました。

設計案1 メインテーブルに mini_app_id カラムを追加する (UNIQUE制約をもつ)

まず、一番シンプルなのが、この設計案だと思います。今回の仕様では1つのミニアプリに対して、 mini_app_id は1つしか指定できなくて良いとのことだったので、正規化を考えてもこの設計になります。

しかし、このテーブル設計にはある問題点があります。それは、過去に設定された mini_app_id を保持していないということです。過去に利用された mini_app_id を自由に使えてしまうと別のミニアプリが再利用を行なってしまった場合、過去のURLが貼られているWebサイトやSNSの投稿などは別アプリを指してしまうことになり、混乱を招きます。

設計案2 別テーブルで liff_id  mini_app_id のマッピングテーブルを追加する

過去に使われた mini_app_id を保持して使えないようにするということで、このテーブル設計を思いつきました。 is_expired  のようなフラグを持たせて、 mini_app_id  is_expired に複合UNIQUE制約を持たせれば、1つの liff_id に対して過去分のレコードを保持しておくことも可能で、 mini_app_id の再利用も防げると考えました。

しかし、柔軟性は低くなります。例えば、一瞬しか使われなかった mini_app_id だから再利用したい、などの要望がある場合には、過去の履歴を消すなどの作業が必要となってしまいます。

設計案3  メインテーブルに mini_app_id カラムを追加し、別テーブルで変更履歴を管理する

この設計は案1と案2を組み合わせたもので、メインテーブルで mini_app_id を管理し、変更履歴は全く独立したテーブルで管理します。この設計では、DBの制約が少ないので、上で述べたようなidの再利用などが可能です。特に、LINEミニアプリはLINE社による審査が人の手によって行われているため、例外的な処理が発生する可能性が高くなります。機械的な制約は、設計が綺麗に見える一方で、逆に運用コストが増やしてしまう可能性があると考えました。したがって、この設計を選択しました。

mini_app_id に使える文字の制約についての工夫

mini_app_id はURLの一部となるので、一般的なURLに使えない文字を禁止するのはもちろんですが、既存の liff_id と区別ができる必要がありました。

liff_id  {10桁の数字}-{8文字の文字列} によって構成されますが、既存のコードの正規表現では、 [0-9]+-\w+ と表現されています。つまり、桁数、文字数に関係なく、 {1桁以上数字}-{1文字以上の文字列} によって、 liff_id と判断されてしまいます。

これを元に mini_app_id の制約を考えるわけですが、今回は、「アルファベット、アンダースコア、数字で構成されている」というルールを選択しました。

このルールは 「 liff_id と区別する 」という目的だけを考えると厳しすぎる制約です。しかし、「{10桁の数字}-{8文字の文字列} はだめ」というルールよりも、「a-z, 0-9, アンダースコアのみしか使ってはいけない」というルールの方がシンプルでMINIアプリの導入企業や開発者、エンドユーザーにとって分かりやすいと考えました。また、 技術的な観点でも、将来的に liff_id の形式が変更になった場合に柔軟に対応できるというメリットがあります。

インターンシップで学んだこと・感じたこと

ここからは自分がインターシップを通して学んだこと、感じたことに関して書いていきたいと思います。

技術面

まず、インターンシップを通じて、多くの技術的な学びを得ることができました。

基礎的な技術面では、Kotlin+Spring Bootでの開発や、Nginxの設定など、これまであまり触ったことのない技術を触ることができました。例えば、Spirng Bootでは、依存性の注入やAOPといった概念を初めて学び、それらを利用してAPIを開発しました。また、コードのアーキテクチャやテストコード設計などに関して、堅牢かつ開発がしやすいコードの書き方を学ぶことができました。

次に、仕様から一番いい設計を考えるということも今回体験することができました。タスクの工夫した点でも書いた通り、機能の技術的な実現方法は複数考えることができますが、開発コスト、運用コストなども考えながら一番いい設計を選択する必要があります。そのためには、技術的な知見をベースに持ちながら、ユーザーの目線に立って考えたり、企画とのコミュニケーションによって認識合わせをすることが大事であり、その部分のスキルも高める必要があると感じました。

そして、特に印象的だったのは、LINEプラットフォームに関わるサービスの規模の大きさでした。LINEプラットフォームに関わるサービスの数とコード量は自分の想像以上の量でした。しかし、その大きさが開発を困難にするわけではなく、それぞれの役割が明確に決まっていて、個々のサービスのインターフェースがしっかり定義されているからこそ、並行して開発を進めることができ、また、1つずつのサービスの開発が複雑にならないということを学べました。大規模アプリケーション開発においては、サービスのコードのアーキテクチャはもちろんのこと、システム全体のアーキテクチャ、仕様策定が非常に重要であると感じました。

また、CI/CDや監視ツールの重要性も再認識しました。リリース作業を見学する機会があったのですが、運用フローがドキュメント化されており、また、複数の監視ツールを用いてリリース時に問題がないかどうかをしっかりとチェックする体制が整っていました。これまでも、このようなツールが大切であることはなんとなく理解していましたが、LINEのような大規模アプリケーションでは障害が起きた場合の影響が特段に大きいため、このようなツールのに対する知見も深めていかなければいけないと思いました。

チーム開発

次に、ここまで大きなチームでの開発は初めてだったので、そこで感じたことを書きたいと思います。

まずは、開発に関わる人数の多さに驚きました。毎週の定例ミーティングには、Native Apps, Front-end, Serverの開発メンバーに加えて、PM、QA、Data Scientist、テクニカルサポートチームの方々が参加していました。他のエンジニアがどのような開発をしているのかも感じることができ、特にQAチームのいる開発は初めてだったので、アプリケーションの品質がどのように保証されているのかを知ることができました。Data Scientistによる様々な分析も大規模アプリケーションならではだと思うので、とても興味深かったです。

そして、チーム開発での開発フローを学ぶことができました。自分が今回取り組んだ機能は、企画の人が提案した機能をもとにPMがタスクの振り分けを行い、それぞれのチームが開発を行うという流れでした。これによって、自分たちがプロダクト全体の中で集中して考えるべき部分が明確になるので、開発がスムーズに進められました。

プリケーションの規模が大きくなると、1人で全体の動きや企画を考えるのは不可能であり、必然的に関わる人数も多くなると思います。その際に、このようにプロダクトが細かく分かれ、さらに各チームに分かれるという役割分担は、開発をスムーズに進める上で必要不可欠なものであると感じました。

アプリケーション開発に関わる様々な職種

エンジニア以外の職種についても、このインターンシップで知ることができました。

回のインターンシップでは、家が近かったこともあり、基本的には毎日オフィスに出社して仕事をしました。その中で、メンターの方が、エンジニア以外の職種の方々ともお話しさせていただける機会を設けてくださり、LINEに関わる様々な職種の仕事に関して話を聞くことができました。

これまでは開発部分しか気にしたことがなく、インターンシップの業務の中でも営業の方などは関わる機会がありませんでしたが、ランチなどでの交流によって、アプリケーション開発を中心に、各職種がどのように連携して会社として利益を生み出していくかを知ることができました。

まとめ・感想

今回、大規模アプリケーションの開発の現場を見てみたいという思いで、このインターンシップに参加しましたが、自分が開発に加わったLIFFはLINEが提供する各種サービスを支える技術でもあり、貴重な体験をすることができました。また、たくさんの社員の方の業務を拝見して、自分の今後のキャリアについて考えるいい機会となりました。

業務以外に関しても、会社の雰囲気がとても良く、オフィスからは東京を360°見渡せてとてもテンションが上がりました!

実際に業務に入りながら、技術も学べて、会社の雰囲気も知れると一石三鳥のインターンシップだったかと思います。

6週間という短い期間でしたが、たくさんの社員の方と交流させていただきました。技術的なサポートだけでなく、交流する機会を提供してくださったメンターの方、レビューや技術的な質問に対応してくださったDP2チームの方々、そしてランチなどでお話しさせていただいた社員の方々に、心から感謝申し上げます。

このインターンを通じて学んだことを活かし、一人前のエンジニアを目指していきたいと思います!