React NativeアプリにFeature Flagsサービスの「Statsig」を導入しました
React Nativeで開発しているアプリに、Feature Flagsを管理できるPaaSである「Statsig」を導入しました。
本記事では導入理由やサービスの選定理由、使用感についてお話します。
Feature Flagsとは?
Feature Flagsとは、同一のコードベースでアプリケーションを提供しながら、ユーザー等の条件ごとに機能のリリース範囲を出し分ける仕組みです。
原理としてはABテストと同じようなものと考えてもらえばよく、ABテストとは違い、ランダムではなく意図的に機能のリリース範囲を制御する仕組みのことをFeature Flagsと呼びます。
ソースコードは「デプロイ」しているものの、すべてのユーザーに対して「リリース」していない状態を作ることで、社内の人間による本番環境でのテストが行えたり、一部の特別なユーザーにのみ試験的に機能を公開するといったリリースフローが実現できます。フラグのON/OFFは管理画面から行うため、全公開するときに再デプロイは必要ありません。
Feature Flagsの導入理由
2ヶ月ほど掛けて実装した大規模なリリースをするにあたって、一気に全ユーザーが利用できる状態で本番環境にリリースすることがリスクだと判断し、まずは社内の人間が扱えるアカウントのみが利用できる状態でデプロイしたいと考えたからです。
原則、ステージング環境までのテストが通っていれば本番環境でも問題ないのですが、ある一定以上の規模になると環境起因のバグは起きやすくなると考えられます。
- ステージングと本番環境のデータ量の違いに起因するバグ
- 本番環境のデータのほうがより「本物である」ことに起因するバグ
- 環境変数によって切り替わっている処理で、本番環境向けの環境変数の設定漏れによるバグ
今回のリリースは事業上かなりクリティカルな機能追加で、かつ決済機能も有しますし、サービスの主要なデータが概ね影響範囲に含まれるようなものでした。
決済については、一般的に以下のように考えて実装すると思います
- 決済機能はInterfaceを用いて実装
- ローカル環境やテストコードではモック化した実装クラスを利用
- ステージングでは決済サービスのテスト環境に向けた上で、実際のクラスを利用
しかしアプリから決済できる機能をリリースするのが初めてだったので、想定外のバグが起きる可能性をリリース前に否定できませんでした。
そもそも、大規模のリリースでなくても、念のためにあらかじめ一部のユーザーにのみ新機能を開放したほうが安全だと言えるケースは多々あると思います。それがもし低工数で安全に実現できるならば、進んで取り組みたいところです。
サービスの導入理由
Feature Flagsの原理自体は簡単です。クライアントからFeature Flagsの有無を判定するAPIにリクエストし、真偽値を返すことでUI上の出し分けを実施します(もちろん、バックエンドにFeature Flagsを導入することで、同一のAPIを叩くが実行結果が異なるといった導入方法もありえます)。
また、同時にFeature Flagsの更新ができる管理画面を社内向けに提供します。
難しい実装ではないように見えますが、私は以下の理由から外部サービスを利用することを判断しました。
- Feature Flagsの品質管理自体を自前で抱え込むリスクがある
- Feature FlagsのAPI実装は非常に高速にレスポンスを返すように実装すればするほどよく、通常のバックエンドAPIと同じサーバーで実装すればいいとは限らない
- 原理は単純に見えるが、実際設計するにあたってはいくつか選択肢があり、ベストプラクティスをしっかり選びきれる自信がない
私の持論として、「自社の事業の競争優位性に繋がらない実装は積極的にSaaSに移譲すべき」というものがあります。自前で実装すると、最初は簡単に実装できても、機能追加やソースコードのバージョンアップといった運用コストも無視できなくなる一方、Feature Flagsを自社で実装していること自体は、本サービスにおいてはなんら競争優位性に寄与しません。
以上の理由から、Feature Flagsを管理できるサービスを検討することにしました。
サービスの選定基準
主に以下の観点を選定基準としました。
- React NativeかつExpo Managed Workflowに対応したSDKを提供している
- (可能なら)VueやPHPといった他言語のSDKも充実している
- 無料または数十ドル程度の一定価格で利用開始でき、当面その費用で維持できることが見込める
- 管理画面ユーザーを複数人招待できる。招待の人数が利用費用に無関係だとなおよし
- 承認フローを設けることができる(当面は私自身のワンオペで行うが、複数人体制になるときレビュー体制を作れると望ましい)
- 公式のSNSやコミュニティが準備されており、活発に動いている
- 運営会社の状況がそれなりに安定していることが見込まれる
2択に絞る過程で落選したサービス
最終的に私はFlagsmithとStatsigの2択で入念に検討しましたが、そこに至るまでに落選したサービスをここで軽く紹介します。
- launchdarkly.com
- 費用感や機能面で不足を感じなかったが、React NativeかつExpo Managed Workflowに対応していない
- https://docs.launchdarkly.com/sdk/client-side/react/react-native
The LaunchDarkly React Native client-side SDK is not compatible with the Expo managed workflow because the SDK uses native modules. Consider using the bare workflow.
- JS SDKを使うといった回避策も浮かんだが、JS SDKは
window
やdocument
を利用しているため使えない - 現実的にSDKを使わずに実装するのは工数面や品質面で考えられなかった
- 費用感や機能面で不足を感じなかったが、React NativeかつExpo Managed Workflowに対応していない
- flagship.io、cloudbees.com
- 初期時点での価格が高かった
- split.io
- 価格表記が不透明だった
結果的に、主にExpoを利用していることと、費用面での条件によって、自分が調べた範囲ではほぼ自動的に2択にまで絞り込めました。
比較結果(表)
それではFlagsmithとStatsigの比較内容について説明していきます。
比較した内容は以下のとおりです。
FlagsmithはPHP SDKがあるところ、あとはドキュメントが読みやすく、モバイルアプリへの導入について専用のページで解説してくれている点などに好感が持てます。それなりに歴史の長いサービスなのか、Slack Integrationもあります。セルフホスティングもできるフルOSSなのでロードマップが見えやすいといった点も嬉しいです。
Statsigはevent
という単位でのみの課金体系で管理ユーザーが無制限な点が親切です。また、SDKの出来がシンプルでわかりやすいように感じました。SDKについては設計思想をブログで公開しており、初期段階から意図を持って設計されていることがうかがえて安心感があります。
比較結果(実装内容)
甲乙つけがたいと思ったので、実際に実装してみて判断することにしました。
Flagsmith
上記のSDKで実装可能です。
SDKで良いと思った点は、
-
onChange
フックでフラグの更新内容を受け取るのが、リアルタイムアプリケーションと相性がよさそう - 同様に、
startListening
関数でポーリングできて、リアルタイムに管理画面からのFeature Flagsの変更を画面に反映できそう
課題点については、
- React Native向けのSDKと言いつつ、React Providerの形式で実装されていない
- もちろん自前でProviderを実装することは可能です
- ポーリングを推奨するかのような仕様になっているのは、おそらくは課金がリクエスト回数ベースだからなので、多用はできない
といった点を感じました。
Statsig
上記のSDKで実装可能です。
SDKで良いと思った点は、
- 以下のようにProviderを使ってReactっぽく実装できる
<StatsigProvider
sdkKey="<CLIENT_SDK_KEY>"
user={{
userID: <LOGGED_IN_USER_ID>,
email: session?.user?.email ?? undefined,
... // other user parameters
}}
options={{
environment: {
tier: getEnv(),
},
}}
>
<Component />
</StatsigProvider>
- SDKがシンプルで、JS SDK→React SDK→React Native SDKの順にラップしていく関係性にあるのが個人的に好み
- Flagsmithは環境ごとにAPIキーを発行するが、Statsigは全環境統一のキーを使う。個人的には環境別にキーを分ける意味をさほど感じなかったので、Statsigのやり方のほうが好みかも
SDKで課題だと思った点は特にないです。Flagsmithと異なりポーリングのAPIが提供されていませんが、公式のSlackに入って質問したところ、ポーリングで判定するのは意図しない動作を画面上で引き起こす可能性があるから、なんらかのアクションをフックにして最新のフラグ値をフェッチするほうがいいよって回答されまして、完全におっしゃるとおりだと思ったので撤回しました。
総じてどちらも悪くないのですが、Developer Experienceがより高いのはStatsigかと感じました。また、管理画面ユーザーの招待が無制限なのも、運営にあたっては助かるポイントなので、僅差ですがStatsigに軍配が上がりました。
ただ、管理画面のUIに関してはFlagsmithのほうが圧倒的に見やすく、操作も直感的で磨き込まれているように感じました。PHP SDKも用意されているわけですし、この記事を書いている今でもどちらを選んでも悪くなかったなと感じています。
2サービスを切り替えながら検証する過程で、必然的にFeature Flagsサービスを使っている部分は独自フックやコンテキストに収まることになったため、今後サービスを切り替えたくなっても影響範囲は限定的にすることができたと思います。
これは余談ですがStatsigは最近シリーズAの資金調達を終えており、なんとなく親近感が湧いたのも0.1%くらいは選定理由にあるかもしれません笑
せっかく導入したので、これからは大規模になりそうなリリースに関してはこまめにデプロイし、社内ユーザーのみにリリースすることでリスクヘッジしていくような工夫もやっていきたいです。
また、Statsig自体にはFeature Flags以外の機能もいくつかあるようなので、機会があれば使ってみたいです。
まとめ
- Feature Flagsを実現できるサービスは意外と多い
- しかしReact NativeのExpo Managed WorkflowではFeature Flagsサービスの選択肢が少ない
- 特にスタートアップにとっては、課金体系が明瞭で、少額から始められるサービスがより好ましい
オンライン家庭教師マナリンクを運営するスタートアップNoSchoolのテックブログです。 manalink.jp/ 創業以来年次200%前後で売上成長しつつ、技術面・組織面での課題に日々向き合っています。 カジュアル面談はこちら! forms.gle/fGAk3vDqKv4Dg2MN7
Discussion