新規アプリ開発を支えるユーザー決済基盤

宇津宏一氏:よろしくお願いします。ユーザー決済基盤部の宇津が発表させていただきます。

みなさん、モバイルアプリ作ってますか? 新しくサービス開発をやっていくにあたって、共通して必要な機能はたくさんあります。

例えばユーザ管理とか認証機能は、だいたい必要ですよね。とくにモバイル時代のユーザー管理や認証に対する欲求というのは複雑になっていて、ユーザーはサービスのアカウントを、クックパッドで言えばクックパッドアカウントでサインインしなくても、利用できるようにする必要があったり。

もちろんデータも保存できるし、後からクックパッドアカウントに登録した場合や他のアカウントでログインした場合も、サインインせずに保存していたデータが良い感じに取り扱われる必要があります。時にはユーザーのアカウントを1つに統合することもあります。加えて1つのユーザーアカウントで複数の端末で利用できるようにするのは、もはや当たり前な時代になっています。

次に、ユーザー決済基盤の観点としては、アプリ内課金も非常に重要です。アプリ内課金は、iOSやAndroidのアプリプラットフォームから提供されている決済機能です。これを用いて、例えばクックパッドば、プレミアムサービスユーザーに登録できる・解約できる機能を実装されています。そうするということは、つまりユーザー管理にも影響があります。

他にも新規にアプリを作るにあたって必要な機能の例を挙げるとキリがないのですが、今回は省略します。

これから見せるのがクライアントサイドの認証フローのステート図です。

これは普通にAPIクライアントを実装するにあたって意識したくないですよね。もちろんクライアントサイドだけではなく、サーバーサイドも同様に複雑なロジックというのが組まれるわけです。

Cuisineとは何か?

ここから本題に入っていきます。では、新規アプリ開発のたびにこれらを毎回実装するのかという話です。

アプリ開発やサービス開始をやっていくにあたって、サービスの機能開発になるべく集中したいですよね。我々はクックパッドの長年の運用で培ったユーザ管理や決済にまつわるノウハウを持っています。なので、それを有効活用して新規アプリ開発を加速したわけです。

そこで、ユーザー決済基盤部として現在取り組んでいるのが、Cuisineというプロジェクトです。

Cuisineはクライアントサイド・サーバーサイドの両方の側面から、新規アプリ開発を加速する取り組みをやっていっています。先ほど4つのアプリを並べましたが、うち3つはCuisineのシステムを利用しています。

Cuisineのクライアントサイド

まずは、クライアントサイドから話していきます。アプリ開発者がサービス機能実装に集中するためにというところで、Cuisineでは主に3つの機能をサポートするクライアントライブラリを開発しました。順番に見ていきます。

まずAPI通信ですが、なるべく認証処理を意識させないかたちにしたいので、認証失敗時には自動で再認証処理をしつつ、API通信をリトライする機能を実装しました。

あとは、プラットフォームごとに使いやすいかたちで、iOSで言えば最近はAPIKitが有名で、これに近いかたちで使えるようにしました。AndroidにおいてはOkHttpで必要なコンポーネント、インターセプターだったりオーセンティケーターを提供するかたちで、クライアントライブラリを作っています。

認証フローとアプリ内課金

2つ目、認証フローについて。

冒頭でお見せしたステート図がうっすら、もしかたら見えてるかもしれません。クライアントライブラリの認証フローはStateMachineで実装しています。加えてライブラリ標準で2パターンの認証フローを提供しているので、大半のケースはカスタマイズが不要な状態になっています。

さらに、認証フローをカスタマイズしたい場合は、StateMachineなんでStateを定義して、Stateに対応したActionを実装して、標準フローを参考にStateMachineGraphを構築することでカスタマイズができます。

3つ目がアプリ内課金についてです。

アプリ内課金というのは、iOS・Androidで仕様も作法もぜんぜん異なります。サポート面も踏まえて「こうあるべき」と言えるような処理フローを実装するには、それなりにノウハウが必要です。

クックパッドでは一連のアプリ内課金にまつわる処理フローは標準化できる見込みがあったので、社内標準化しました。正常系のフローはもちろんのこと、発生しうる異常系とそれに対するユーザーへの見せ方が整備された状態になっています。

その上で、この標準フローに沿ったクライアントライブラリをCuisineのクライアントライブラリとして提供することで、標準の処理フローに基づいてアプリ内課金を実施できるようになっています。

というわけで、Cuisineではクライアントライブラリを提供して、クライアントサイドの複雑さを吸収して新規アプリ開発を加速していっています。

Cuisineのサーバーサイドについて

では次に、サーバーサイドの話です。クックパッドではここ数年、マイクロサービスをやっていっているって状況です。要するにクックパッド本体から、徐々にサーバーアプリケーションの分離が進んでいます。

これがクックパッドアプリにまつわるアプリケーション構成です。

アプリはリバースプロキシを経由して、クックパッドのAPIや、すでに分離されているマイクロサービスにアクセスします。その先には決済基盤やユーザー基盤があります。

あくまでもこれらは、クックパッドやクックパッドアカウントを利用しているアプリ・Webから利用される前提で構築されてきました。

ここに新規アプリが出てきます。

冒頭で述べていたような課題を解決するにあたってどうしたらいいか。まず、決済サービス、決済基盤やユーザー基盤には、クックパッド固有の機能……例えばクックパッドから送られてくるメールマガジンの受信設定が挙げられます。こういったものはユーザー基盤に乗せて個別にやっていきます。

そして、ユーザ管理・アプリ内課金の定期購読にまつわるビジネスロジックを持つ、cuisine-apiを新設しました。

事前にアプリケーションの登録、サーバーサイドの設定をしていただくとこのAPIを利用できます。かつ、先ほどお話したクライアントライブラリが、すでにこのcuisine-apiとのつなぎ込みをやってくれているので、以降はサーバーアプリケーションの開発に集中できる状況になっています。

「定期購読のAPI」とありますが、アプリ内課金には、定期購読の他にも都度課金の仕組みがあります。そちらについてはサービス固有の取り扱いになりやすい側面があって、標準化された決済フローも提供していますが、必要に応じてサービスごとに実装してもらっています。

補足になりますが、cuisine-apiを利用している新規サービスというのは、もちろんクックパッドの認証システムに乗っているので、レシピ情報といったクックパッドのリソースも参照することができます。

こういったかたちでCuisineプロジェクトのサーバーサイドは進行しています。

「Organized Around Business Capabilities」

こんな感じなんですが、あくまでもクックパッドの実践例というのは抑えておいてください。単純に「共通実装にしたんですね」という話では、僕はないと思っています。Cuisineプロジェクトとしてこれらのシステムやライブラリを構築するあたって大事にしていることがあって、それは「Organized Around Business Capabilities」という言葉です。

これは、マイクロサービス、ひいては進化的アーキテクチャの性質・特徴と言われているものです。現在クックパックの新規サービスは、クックパッドのリソースは参照しつつも、独立したビジネスをやっていています。

そうなった時にユーザー決済基盤としては、一番優先度を上げて取り組むべき業務というのは、これまで述べてきたとおりユーザー管理・決済機能をより速く導入できるようにする。そう考えた上で今のCuisineプロジェクトが進んでいます。

これが仮に、「プレミアムサービス登録ユーザー数を増やす」といった目的のための新規サービス展開であったらどうだったか。そうなった場合ビジネスの主体は、今までどおりクックパッドのアプリやWebの会員事業になりますよね。そして各新規アプリで定期購読を契約すると、クックパッドのプレミアムサービスも付いてくる、みたいなビジネスプランが考えられます。

そうなった時に、ユーザー決済基盤としては、クックパッドと新規サービス間のユーザー管理・決済状態を不整合なく同期できるアーキテクチャの構築が、一番重要な業務になるでしょう。もちろん速く導入できるようにすることも要件としてはありますが、そちらが優先されます。

つまり何が言いたいかというと、今cuisine-apiはこうなっているんですが、ビジネスの方向性によってはオーケストレーションAPIという位置にある必要はありません。

新規サービスのバックエンドにあってもいいと。加えて先ほど述べたようなプレミアムサービスのユーザー獲得を目的とするのであれば、そもそもAPIを新設する必要もないわけです。

ビジネスの方向性によってはこういう未来もあったでしょう。

クライアントライブラリのかたちも変わっていたと思います。ちょっと説明として不十分なところもありますが、つまりビジネスの方向性、ビジネスのオーナーシップをちゃんと念頭に置いた上で、より新規サービスのユーザー認証・決済機能の導入を加速していっているというのが、Cuisineプロジェクトになります。で、サーバーアプリケーションの構成もそれによって左右されます。

開発コストの削減のために共通のなにかを作っていくことはみなさんもあると思います。その時にビジネスの視点だったり、何に注力すべきか、何を共通化すべきかという視点ですね。ビジネスの方向性という視点があると、どこまでそこに乗せてこれは要らない、といった区別がつきます。ぜひ参考にしていただければなと思います。

Cuisineの今後について

では、今後の展望についてお話ししていきます。実装コストの面について、Cuisineは多くの活躍を見せました。もちろんサーバサイドもクライアントサイドもロジックを共通化しています。

ですのであとはしっかり、標準化や処理フローを図に落としたり、ちゃんとドキュメントを最新化、最新の仕様に追従し続けることを維持してきたので、サービス開発者の理解・可読性にも貢献しました。

とはいえ課題は山積みです。やはり積み上げてきたノウハウそのものが難しいです。

ここでに「マージ」って書かれてるんですけど、これは社内用語で「アカウントの統合機能」を指しています。仕様の策定に関わっているエンジニアですら混乱するくらい難しい状態になってるんですね。

Cuisineとしてはなるべく意識させないようなかたちにしていく必要があるし、こうやって処理フロー自体の簡略化というのもちゃんと検討していかなきゃいけないと考えています。

続きましてサーバーアーキテクチャなんですけど、クックパッドの新規サービスはそれぞれ独立したビジネスをやっているというお話をしました。それぞれ独立しているってことはですね、クックパッドアプリも独立しているってことになるんですよね。

なので将来的には、クックパッドのアプリからもcuisine-apiを参照するようにしたい。で、クライアントライブラリの導入も進めていきたい、という構想を抱えています。まだ構想段階です。

今回はあまり深く触れられませんでしたが、実装面以外にも課題はたくさんあります。課金機能が絡んでくると、法的手続きや返金ポリシーの策定だったりとか、決めなければならないことがたくさんあります。で、ディレクター陣の負担が非常に高い。

なので導入時のロードマップをちゃんと整備するとか、共通化可能なものは共通化していくというのは、負担を軽減する意味でどんどんこれからも取り組んでいきたいなと考えています。

テストの実施についても、「導線のぶれはあるけれど大筋の項目は変わらなそう」という見解があるので、こちらも半自動化や自動化など、そういった改善の余地があるなと考えています。

というように、引き続きCuisineプロジェクトを推進して、新規アプリをより速くリリースできるようにしていきたいと考えています。

最後になりますが、スライドからこぼれ落ちたトピックがいくつかあります。

心当たりある方はぜひ、のちほどお気軽にお声かけください。ご静聴ありがとうございました。

(会場拍手)