eギフト発行基盤共通化への取り組み
※giftee engineer blogから転載
(この記事は2023年に取材・執筆されたものであり、記事内の部署名や役職は当時のものです)
eギフト発行システムの共通プロキシを作成する取り組みについて
こんにちは、ギフティでエンジニアをやっている中屋です!
私は GiftExperince dev unit というチームに所属しています。 このチームは割と最近誕生した unit になっていて、Experience と名が付くように、ギフト体験の価値を最大化していくことを主なミッションとしています。各プロダクトで個別に実装されニーズ検証された機能の共通化や、eギフト発行に関わるシステム構成の歪み、既存の技術的負債等を解消することで、エンドユーザーや運用担当者、クライアントシステム含め全体に対してより良いギフト体験の提供に貢献していこうという狙いがあります。
そのための第一歩として、eギフト発行の共通基盤の開発に取り組んでいるので、この記事ではそれについて紹介しようと思います。
はじめに
ギフティは創業してから10年以上が経ち、その間様々な事業の展開に合わせてたくさんのプロダクトが作られてきました。 最初は toC 向けのeギフト事業として始まり、そこから法人向けや地方公共団体など色々なクライアント向けのプロダクトが作られ、今ではeギフトそのものに留まらず、縁を育むサービスとして幅広くプラットフォーム展開をしていこうというビジョンがあります。
そんな事業の伸びに比例してエンジニアの数も増え、今では社内に大きく4つの開発組織があります。さらにその中で各プロダクトごとにチームが分かれているという規模感になってきました。
その各チームで開発しているシステムどうしは全く独立しているというわけではなく、有機的に連携して動作する必要がありますが、これまでは事業が先行しそれを実現する形で MVP(Minimum Viable Product) を積み上げて来た背景があるので、どうしても連携部分が弱いというか、非効率になっているところがあったりします。
そうした変遷の中、中にはシステムができることとビジネスがやりたいことの歪みが大きくなったり、個別最適化されていて汎用的に使えなかったり、単に古くレガシーになってしまったプロダクトというのも当然あります。 そういった背景から、新規プロダクトの開発と並行して、既存システムのリニューアルなどが社内各地で行われていたりします。
そうした活動の一部はこのエンジニアブログの記事になっているので興味があれば読んでみてください。
eギフト発行基盤共通化
現状のシステム構成
さて、色々な技術的負債がある中、記事のタイトルにもある通り、この記事ではeギフト発行基盤共通化への取り組みについて書きたいと思います。 弊社はeギフトを中心としたサービスを展開していますが、eギフトを生成するシステムと、それを個人に販売したり、法人利用でユーザーに配布したりといった使い方があり、それぞれシステムが分かれています。 この記事内ではそれぞれ以下のように名前付けしておきます。
eギフト生成システム
=> eギフトを生成するシステム
eギフトの生成とは、つまり金券相当のデータとそれに付随したギフトカードなどのデータを作ることと言えます
ソリューションシステム
=> eギフトを販売したり、生成されたeギフトを使って何らかのサービスを提供したいシステム
toC 販売、法人キャンペーンなどを管理したり、その結果生成されたeギフトを配布したりします
このeギフト生成システムですが、歴史的な背景やギフトの形態の違いなどもあり、いくつかの複数のシステムに分割されて構築、運用されています。
そもそもeギフトと一口に言っても、店舗受け取り型(店舗で商品と交換できるもの)や配送型(受け取り手が住所を入力すると自宅まで配送してもらえるもの)、地域通貨として使えるもの、社内ノベルティなど、細かく分類すると様々な種類のものがあります。現状では、そうしたいくつかの用途ごとにeギフト生成システムが分かれています。どのシステムもeギフトを発行するという点では共通していますが、それを取り巻く機能や求められる機能/非機能要件、政治的背景が異なっているため、それぞれに特化したシステムを構築しているという感じです。そしてここは今後もeギフトのラインナップの拡充とともに増えていくことが予想されます。
また一方で、ソリューションシステム側はというと、こちらも複数のシステムに分かれています。エンドユーザーに一番馴染みがあるものですと、giftee の販売サイトになります。そのほかに法人向けのプロダクトがいくつもあり、それぞれがeギフトを使ったなんらかのソリューションを提供しています。ギフトをユーザーに届けるという目的自体は一緒ですが、ファンクショナルな部分の要件は全く異なるため、システム自体が分かれています。 特に法人利用の場合、eギフト自体がどのような用途で使われるか、今後も使われ続けるかがビジネス的に予測しづらいこともあって、PoC 的にポコポコとサービスを立ち上げては実験するを繰り返しているので、システム数がどんどん増えていってます。 そして、各ソリューションシステムは自分が欲しいeギフトを発行するために、各eギフト生成システムへ Web API 経由で発行リクエストを行っています。
ここまでの話をすごくデフォルメしてざっくり書くと以下のような図になります。
現状の問題点
eギフト生成システム、ソリューションシステムは年々その数が増えてきています。 現状の構成上、以下のような課題感があります。
新しいソリューションシステムが増えた際に、自分が必要としているeギフトを発行してくれるeギフト生成システム分だけ別々に Web API を繋ぎ込まないといけなく、接続コストが高い
IF の理解やリトライ処理、eギフト生成システム側のレートリミットなどを勘案する必要があり、接続するにあたって把握しなければならない情報が多い
eギフト生成システムの中にはさらに外部の API (他社サービス)を叩いていたりするものもあって、ものによってはレートリミットが厳しかったり、システム自体が不安定だったりする
新しいeギフト生成システムが増えた際に、それを使いたい既存の全てのソリューションシステムはその API の繋ぎ込みをしないといけない
とあるeギフト生成システムで実装された機能が、別のeギフト生成システムでは使えず、車輪の再発明になる場面がちょくちょくある
個々のeギフト生成システムがお試し的に実装してみた機能が、実はすごく需要があって他でも使いたくなるなど
eギフト発行基盤共通化というアプローチ
システム数が増えるにつれ、上述した問題が看過できなくなってきており、そうしたeギフト発行周りの様々な問題を解決するために組成されたのが、我々 GiftExperince dev unit チームです。
チームとして色々やりたいことがあるのですが、ファーストステップとしてまずは Web API の繋ぎ込みコストの部分に焦点を当てて考えていくことにしました。
繋ぎこみコストの問題を解決するために、eギフト生成システムの手前にプロキシを置くことでeギフト生成リクエストの口を一元化するという方針を取りました。 図にすると以下になります。
図の真ん中にあるeギフト発行ゲートウェイというものを新しく作り、発行 API コールの仲介をします。
また、全てのeギフト生成システムの全ての商品を管理するグローバルな商品マスタも新たに用意します(ちなみにこのマスタは我々のチームではなく、また別の横断チームが開発しています)。
こうすることで各ソリューションシステムがゲートウェイの裏にいる具体的なシステム構成を意識しなくて良いようになります。 これにより API 接続の数を減らし、また、生成システム側が増えたときに API 自体の接続の調整をしなくて良くなります。
加えて、ゲートウェイは内部的に発行キューを持っていて、eギフトの非同期発行をサポートしています。eギフトの発行シチュエーションの中にはeギフト URL は必要なんだけど、eギフト券面そのものはすぐに必要ではないケースがあります。例えば、法人利用などで事前に発行だけを行い、後でユーザーに配布するというケースでは、発行と利用の間にそこそこのタイムラグが発生します。加えて、問題点のところで触れましたが、eギフト生成システムの中には外部システムに依存していて、可用性を我々の社内だけでは担保できないシステムがあります。そうしたシステムへ直依存してしまうと全体の可用性が低くなってしまいます。そこで、ゲートウェイの内部にキューを設けて、非同期的にeギフト発行を処理できるようにしています。具体的には以下のような流れになっています。
ソリューションシステムからゲートウェイが発行リクエストを受け付け、ゲートウェイが採番した URL を返す
ゲートウェイは非同期でeギフト生成システムに発行をリクエストし、発行が成功した場合、リターンされた URL をゲートウェイ採番の URL に紐付ける
ゲートウェイが採番した URL にアクセスすると、非同期で発行されたeギフトの URL にリダイレクトする
この際保険として、非同期による発行が完了していない場合、同期的にeギフトを発行してからリダイレクトするようにする
こうすることで、eギフト生成システムの可用性に依存せず、eギフト発行の受け付けができるようになります。 ちなみに、ここの非同期処理は SQS と Lambda を用いて構築しています。
取らなかった選択肢
上記を対応するにあたって、取らなかった選択肢についても書いておきます。
上述したプロキシを置く以外の選択肢として、共有ライブラリあるいはサイドカーコンテナを作りソリューションシステム側に配布して使ってもらう、というものも考えられました。これらは単一障害点を減らせたり(プロキシ自体が単一障害点になってしまったため…)、通信レイテンシーが比較的良いなど魅力的な点がいくつかありました。 しかし、以下の理由から今回は採用しませんでした。
共有ライブラリの場合、ソリューションシステムが使用している全ての言語に対応する必要がある
現状 Ruby が多いが、違う言語のソリューションシステムが出てきた時に、我々のライブラリ開発がボトルネックになるのは避けたい
サイドカーコンテナの場合、ソリューションシステム側でコンテナの運用がされている必要がある
また、サイドカーパターンへの理解も一定必要になる
ソリューションシステムの中には社内システムだけでなく、協業先等、外部のシステムがいることも予想され、上記の前提を全部のシステムに求めるのは厳しそう
また、プロキシによってうまく抽象化できるのであれば、そもそもeギフト生成システムを一つのシステムに統合できるのでは?という話も挙がりました。確かに理想としては良さそうですが、いきなりそこを目指すのもリードタイムが長すぎるというのと、歴史的背景から分けざるを得ないシステムなどもあり、直近の対応としては難しいので、別の方法でペインを解消しつつ検討を進めようとなりました。
終わりに
eギフト発行周りの技術的負債に関して、初手の取り組みとしてeギフト発行基盤共通化への取り組みについて紹介しました。eギフトの発行周りはまだまだ解消すべき問題が山積しています。今後は共通で提供されるべき機能の共通化に取り組んだり、eギフト発行時における新しい価値を提供できる機能開発などを推し進めていく予定です。そこはまた別の記事で紹介できればと思います。
ギフティではeギフトプラットフォームを作っていくメンバーを大募集しています。
興味のある方はカジュアル面談など、ぜひお気軽に参加してくだされば嬉しいです。