freeeの開発情報ポータルサイト

【連載 第1回】freeeカード Unlimited の開発の道のり

金融チームでエンジニアをしているimamuraです。freeeカード Unlimited のβ版の提供が今年(2021年)の秋から開始されます。開発自体は半年以上かかっており、そこでの開発の裏側について連載を行います!

連載は以下のようになります。 ※ 日程、タイトルは一部変更になる可能性があります

日程 タイトル 執筆者
9/9 freeeカード Unlimited の開発の道のり imamura
9/16 freeeカード Unlimited での非同期通信の設計と実装 imamura
9/23 EMから再度エンジニアに戻り新規プロダクト開発に挑戦して学んだこと tabachain
9/30 freeeカード Unlimitedでのクリーンアーキテクチャ実践 id:lvmingbei
10/7 新卒一年目からの新規プロダクト開発 sekky
10/14 新規プロダクト&新造チーム&フルリモート:EMに何ができるか? yokota
10/21 カード事業のインフラ作ってみた id:renjikari
10/28 QAがスクラムチームの一員として取り組んでること yumotsuyo

そして、第一回のこの記事では freeeカード Unlimited がどういったアーキテクチャになっており、どのような技術を利用しているのか開発の全体像を共有していきたいと思います。

freeeカード Unlimited とは

freeeカード Unlimited
freeeカード Unlimited

freeeカード Unlimited とは、freeeが提供する法人向けのコーポレートカードです。freee会計に銀行口座を同期している法人であれば、freee独自の与信モデルにより、創業期の法人であっても高い限度額でカードを利用することができます。それによって、代表者の個人信用情報によらず広告費やサーバー代など高額になる支払も可能になります。また、カード決済後すぐに通知され、freee会計に明細をすばやく同期することができるため、タイムリーな月次決算を行うことができます。

現在は、β版のリリースに向けて開発中で、社内で実際に利用(ドッグフーディング)しながら改善を行っています。

サービスのアーキテクチャ

freeeカード Unlimited は以下のようなマイクロサービス群で構成されています。

サービスの構成図
サービスの構成図

Backend For Frontend (BFF)が、クライアント用のAPIを提供し、背後にあるサービス群と通信します。それらは以下のような役割を担っています。

  • カード管理: ユーザーのカードの管理(申込、発行、停止など)をする
  • 決済: カード利用時に残高を確認し決済可能か応答する
  • 請求: カードの利用額の請求処理をする
  • 与信: カードの毎月の利用限度額を決める
  • 通知: 他サービスのイベントに応じた通知をする

各サービスは、主に非同期で通信します。

マイクロサービスの採用

マイクロサービスとは、アプリケーションを個別にデプロイできる疎結合のサービスの集合として構成するアーキテクチャです。そして、今回マイクロサービスをアーキテクチャとして採用した理由は以下が挙げられます。

  • 個々のサービスを小さくして開発しやすくなる
  • 個別にデプロイやスケーリングができる
  • 変更や障害の影響を分離できる
  • データソースを分離できる

もちろん、マイクロサービスを採用しただけで、個々のサービスの開発のスピードが上がったり、障害の分離が実現されるわけではありません。なぜなら適切にサービスを分割しなければ、あるサービスの変更をするために他のサービスの実装を参照したり、変更を加えて一緒にデプロイしたりしなければならない状態に陥るからです。

freeeカード Unlimitedの開発では、アプリケーションが対象とするユーザーに纏わる活動や関心事を洗い出し、どういった概念が登場し、それらがどのように関係しているのか言語化することから始まりました。開発初期の1ヶ月以上の時間を使って、チームで議論しました。

具体的には、イベントストーミングという手法を使ってモデリングをしていくことから始めました。これは開発のメンバーだけでなく決済領域に詳しいPMにも参加してもらって、アプリケーションで発生する出来事を時系列で書き出す作業です。そうすることによって、登場する概念を確認し、それらがどんな出来事が起因して影響を与えられるのかを可視化することができます。その過程で、例外的なケースを質問したり、概念を包括できるまとまりを見つけ出すことができます。

イベントストーミング
イベントストーミングの様子

このイベントストーミングで整理した情報をもとに、サービスの分割案を作っていきました。そして、サービス間で必要となるAPIを整理してサービスの境界を見直していきました。まずはシンプルな設計から始めたかったのでサービスを跨いだトランザクション処理がないようにも設計しました。

サービス間通信

サービスの分割案ができて、それぞれAPIが決まったのであれば、どう通信するのかを決める必要があります。 まず、サービス間の通信には同期と非同期があります。それぞれ以下の特徴があります。

  • 同期
    • リクエスト先のサービスが応答可能である必要がある
    • 処理が終わってレスポンスが返ってくるまでブロッキングされる
    • すぐにリクエストが処理される
  • 非同期
    • メッセージがバッファリングされるため、リクエスト先のサービスが応答可能でなくて良い
    • メッセージ配信サービスが応答可能である必要がある
    • リクエストして次の処理に進める
    • リクエストが処理されるまで時間がかかる

サービス間の同期的な通信は、gRPCを使って実現しています。freeeカード Unlimited ではインターフェース定義語(IDL)である Protocol Buffers (protobuf) から生成されたコードを利用してRPCをしています。後述するように、モノレポでprotobufを管理することで、統一的にRPCのインターフェースを各サービスで共有することができます。

また、BFF以外のサービス間の通信は非同期のパブリッシュ・サブスクライブの通信が中心になっています。各サービスは発生したイベントに応じたメッセージをメッセージブローカー(サービス間のメッセージの仲介をする配信サービス)に送るだけで、それがどのサービスでどう扱われるか関知しません。そうすることによって、サービス間を疎結合にすることができます。そして、メッセージブローカーは Amazon SNS と Amazon SQS を利用しています。

モノレポの採用

freeeカード Unlimited ではモノレポ(Monorepo)を採用しています。つまり、各サービスの実装は一つのリポジトリで管理されています。モノレポを採用した背景としては、リリースするまでの間は少なくとも一つのチームが全てのサービスを並行で開発をする必要があったためです。単一のリポジトリにまとまっていることで、複数のサービスを開発する場合でもCloneは1回で済み、1つのPull Requestで複数のサービスの開発を進めることができます。そしてサービス全体のコードの可視性を高めることができます。

また、protobufを利用してサービス間のAPIを定義した場合、リポジトリがサービスごとに分かれていると、どこで管理し、どう共有するかが課題になります。freeeカード Unlimited ではモノレポで統一的にprotobufを管理し、1つのコマンドで各サービスのディレクトリ配下にコードを生成するようにしています。

モノレポでのprotobufの共有
モノレポでのprotobufの共有

技術スタックと開発プロセス

freeeカード Unlimited のBFF以外のサービスのバックエンドはGoを使って実装されています。採用した理由は、静的型付けやシンプルで理解しやすい言語設計だけでなく、社内でマイクロサービス向けの共通パッケージが用意されているからです。これは社内にいくつもマイクロサービスが存在し、微妙に構成が異なった実装や車輪の再発明を防ぐために提供されました。例えば、ロギングや、エラー通知、SQLの実行、リトライなどのパッケージが用意されています。これによって、ドメインロジックの実装に集中することができました。

また、フロントエンドの実装はTypeScriptとReactを使って実装しています。社内ではReactの共通UIコンポーネントが用意されており、それらを使うことでマークアップやスタイルシートで悩むことなくUIの実装ができるようになっています。

そして、全てのサービスはAmazon EKS上で稼働しています。また、他のプロジェクトと同様にスクラムスプリントごとに開発しており、機能が実装されるとすぐにデプロイしてQAしています。

これらの技術や取組に関しては後の連載で紹介していきます。

まとめ

freeeカード Unlimited はビジネスカードの管理や決済時の即時応答、請求、与信を担うため、高い可用性やデータの整合性が要求されます。そして、決済にまつわる複雑なドメイン知識を理解しながら、設計・実装しなければなりません。だからこそ、常に良い手法や技術を選定し改善していくことができるプロジェクトであると感じています。今回は freeeカード Unlimited の開発に関する全体像をお伝えすることができたかと思います。この後の連載では、より詳細にどのような開発が行われたのか共有していくつもりです。

次の連載は、再び自分から「freeeカード Unlimitedでの非同期通信の設計と実装」について紹介していきます!

developers.freee.co.jp


金融チームでは、一緒に「freeeカード Unlimited」を開発する仲間を募集しています。 ベンチャー企業であるfreeeの中でも更にスタートアップ色が強い金融チームで、スモールビジネスの資金繰りにイノベーションを起こしましょう! https://freeecommunity.force.com/jobs/s/detail/a4l2r000000CaUpAAK