3分で作れるお手軽リリーストグル
サマリ
- フロントエンドのリリーストグルは1つのTSファイルで実現できます
- BigQueryとRedashで可視化すると機能のリリース状況が一目瞭然になります
はじめに
はじめまして@yoshimaru46です。toB SaaSを開発する中でリリーストグル[1]が便利だったので、その実装方法を紹介します。[2]
リリーストグル導入の背景
現職では医療機関向けにSaaSを提供しており、以下のような特性がありました。
-
複雑なドメイン
医療という複雑なドメインの中で、「正しいもの」を作るために、実際にユーザーに使ってみて価値を検証する必要がある。 -
0 -> 100 (All or Nothing) のリリースは危険
エラーが発生すると現場の業務に支障が出る
「正しいもの」を作るためにどんどんデプロイしたい。 一方で エラーの発生、顧客の業務への影響を最小限に抑えたい。 そういった思いからリリーストグルという仕組みを導入しました。
手軽なリリーストグルの実現方法
やったこと
フロントエンドのリポジトリに以下のようなリリーストグルの設定ファイルを作成しました。
export const DARK_LAUNCH_KEY = {
ENABLE_NEW_AWESOME_FEATURE: 'enable_new_awesome_feature'
} as const;
export type DARK_LAUNCH_KEY = typeof DARK_LAUNCH_KEY[keyof typeof DARK_LAUNCH_KEY];
type DarkLaunchConfig = {
key: DARK_LAUNCH_KEY;
description: string;
hospitalIds: number[];
};
const darkLaunchConfigs: DarkLaunchConfig[] = [
{
key: DARK_LAUNCH_KEY.ENABLE_NEW_AWESOME_FEATURE,
description: 'すごく便利な新機能',
hospitalIds: [
100, // A病院,
200, // B病院,
300 // C病院,
]
}
];
export const darkLaunchVariation = (key: DARK_LAUNCH_KEY, hospitalId: number): boolean => {
const config = darkLaunchConfigs.find((c) => c.key === key);
if (config == null) {
return false;
}
return config.hospitalIds.includes(hospitalId);
};
リリーストグルの設定ファイル
import { DARK_LAUNCH_KEY, darkLaunchVariation } from '~/util/darkLaunchUtils';
~~~
const hospitalId = 1; // IDはいい感じに取得
const isEnableNewFeature = darkLaunchVariation(DARK_LAUNCH_KEY.ENABLE_NEW_FEATURE, hospitalId);
~~~
isEnableNewFeature && (<Button>新機能</Button>)
リリーストグルを利用するコンポーネント
リリーストグルの実装により、新機能を社内や一部の医療機関のみを対象に事前にデプロイできるようになりました。機能の価値を検証し、適切な改善を行った上で全体にリリースしています。
また、Effective DevOpsでも紹介されていた継続的インテグレーション[3]が実現され、安全なリリースが実現できています。
TypeScriptで型がつくので設定時のtypoを防ぐことができ、機能を100%リリースした後にコードを削除[4]するのも簡単です。
やらなかったこと
動的に設定を管理
リリーストグルの特性上、静的に管理する方がInfrastructure as codeの恩恵を受けることができるので良いと判断しました。[5]
SaaS, OSSの利用
Feature Togglesに関しては、LaunchDarklyなどのSaaSやUnleashなどのOSSも存在しています。
今回の課題としては1ファイル作るだけで十分でしたので一度見送りました。
サーバーサイドでの機能の出し分けなども増えてきたら再度検討する予定です。
BigQueryとRedashで機能のリリース状況を可視化
リリーストグルの実装後、POやユーザーサポート、QAチームのメンバーから、「どの機能がどの医療機関にリリースされているか把握したい」という声が上がるようになりました。
そこで設定ファイルの内容をBigQueryに同期し、Redashで可視化できるようにしています。[6]
RedashのPivot Tableを利用
終わりに
今回は省エネで実装しましたが、必要になったタイミングでSaaSやOSSを試してみようと思います。
参考にした記事
- KeystoneInterface
- Feature Toggles (aka Feature Flags)
- "雑" / Almost Microservices
- FastlyとTypeScriptで実現するカナリアリリース
-
リリーストグルについては Feature Toggles、「Release Toggles」が詳しいです。 ↩︎
-
Effective DevOps、継続的インテグレーション「マージとマージの感覚が長くなれば、変更された部分が多くなる。そして、それらの中に問題のあるものが含まれる可能性が高くなる。一回のコミットでの変更量が大きくなれば、問題を起こした原因を特定し、それを分離するのが難しくなる。一回のコミットでの変更量を小さくして頻繁にマージすれば、リグレッションを引き起こした変更をはるかに見つけやすくなる。継続的インテグレーションの目標は、大規模で頻度の低いマージが引き起こす問題を防ぐことである。」 ↩︎
-
運用コストを減らすために不要になったトグルは積極的に消していくと良いです。 ↩︎
-
Feature Toggles、「Prefer static configuration」を参考にしました。 ↩︎
-
BigQueryへのデータの同期にはgoogleapis/nodejs-bigqueryを利用しています。 ↩︎
Discussion