Gaudiy Tech Blog

Gaudiyの技術、開発組織、カルチャーについてお伝えするブログです

Gaudiyがフロントエンド開発でフィーチャーフラグをどう使っているか

f:id:gaudiy:20210812085458p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている高島(@takashima_katsu)です。

弊社では最近、フロントエンド開発で「フィーチャーフラグ」の運用を開始しました。

フィーチャーフラグは「信頼性を保ちつつ開発スピードを高める手法」として知られていますが、その運用はプロダクトの特徴や開発のレイヤー、チームの特性などによって様々だと思います。

そこで今回は、Gaudiyでのフィーチャーフラグ導入の背景や、実際の運用の仕方、1ヶ月ほど運用する中で感じた気づきや学びについてブログにまとめてみようと思います。

※フィーチャーフラグはフィーチャートグルとも呼ばれますが、この記事ではフィーチャーフラグの名称を使用しています。

なぜ導入したのか

導入の背景としては、Gitフローからトランクベース開発へと開発手法を変更したことがありました。

それによって、メインブランチを常にリリースできる状態に保つ必要が出てきたことから、そのための手法としてフィーチャーフラグの運用を始めることになりました。

※トランクベース開発への移行背景などは、弊社の @winor30 が前回のブログに書いていますので、併せてご覧いただけると嬉しいです。

techblog.gaudiy.com

フィーチャーフラグとは何か

そもそもフィーチャーフラグとは、「コードを変更することなく 、システムの動作を機能(フィーチャー)単位で動的に変更することができる」開発手法です。

これにより、機能ごとにオン / オフを切り替えることができるようになります。(詳しくは以下の記事がわかりやすかったです。)

martinfowler.com

フィーチャーフラグの種類は複数ある

フィーチャーフラグの種類は複数あります。どのフィーチャーフラグも、機能ごとにオン / オフを切り替えることができるものですが、どういった理由で切り替えたいのかによって使う種類が異なります。そのため、どのフィーチャーフラグを運用するかは、プロダクトや開発のレイヤー、組織によっても変わってきます。

弊社の場合は、現在フロントエンド開発で「リリースフラグ」「アクティベーションフラグ」の2種類のフィーチャーフラグを運用しています。

1. リリースフラグ

これは、Gitフローで開発していた時のフィーチャーブランチの代わりになるフラグです。新機能のリリースやリファクタリングの際に使用され、リリース後にはコードからもデータからも削除されることが想定されるものです。

2. アクティベーションフラグ

これは、テナントによって提供する機能を出し分けるためのフラグです。特定の機能をもつテナントにはリリースしたいけれど、他のテナントにはリリースしたくないときなどの制御に使います。

弊社では複数のテナントが存在するプロダクトを単一のコードで提供しているため、このアクティベーションフラグを活用することで各テナントごとに機能を提供できています。リリースフラグとは違い、その機能が全体を通して削除されることがない限り、半恒久的に使用されます。

フィーチャーフラグの実装方法

大まかな流れとしては、BFFで計算してbooleanで返却し、その値でフロントエンドで制御しています。

データベース

フィーチャーフラグに必要な値はFirestoreで管理しています。 ドキュメントIDを機能名にして、フィールドに releaseFlagactivationFlag を持っています。

BFF

マイクロサービスアーキテクチャを採用しており、フロントエンドからマイクロサービスへのアクセスをシンプルにするためにもBFFを設けています。 GraphQLとApollo Serverで構築されており、BFFからFirestoreの値を参照して、それを元に計算しています。 具体的には、以下のようなスキーマを用意しています。

# query.graphql
type Query {
  featureFlags: FeatureFlags!
  ...
}

# schema.graphql
type FeatureFlags {
  id: ID!
  chatReleaseFlag: Boolean!
  postReleaseFlag: Boolean!
  postActivationFlag: Boolean!
  ...
}

フロントエンド

Next.js でフロントエンドを構築しており、 Apollo Client でデータの取得をしています。

const Component = () => {
  const { chatReleaseFlag } = useChatReleaseFlag();
  return <div>{chatReleaseFlag ? <NextComponent /> : <PrevComponent />}</div>;
};

フラグの種類が増えてくると、コードがフラグだらけになってしまいメンテナンスコストが高まってくることが予想されるので、フラグはできるだけ上位のコンポーネントに置き、散在させないことを意識することが大切です。

フィーチャーフラグの運用方法

管理しているフィーチャーフラグの数が増えてくると、どのフラグがどのようなステータスなのかを把握するのが大変になってきます。

また弊社のプロダクトの関係上、BizDevやコミュニティマネージャーなどのエンジニア以外の人ともどういった機能がリリースされているかなどを把握し、全社共通の言葉として使っていかなければなりません。

そのため、今どのようなフラグがあり、どういったステータスなのかを誰でも確認できるようにしています。(弊社では情報管理のアプリケーションとしてNotion を活用しているので、一覧で確認できるページを作成しています。)

f:id:gaudiy:20210811232222p:plain
Notionで作成した「フィーチャーフラグ一覧」

運用してみての課題 & 改善

まだ運用してみて日は浅いですが、以下のような点は課題だと感じています。

1. コンポーネント設計次第ではフラグを置く位置が多くなってしまう

特に既存のコードにフラグを置くときは、もともとフラグを置く想定をせずにコンポーネント設計をしていたため、散在してしまうこともありました。

2. フィーチャーフラグの切り替えで直接データベースを触っている

エンジニア以外の人が変更することもあり、直接データベースを触るやり方はミスが発生しやすくなります。それを防ぐには、管理画面を用意して切り替えられると良いかと感じています。

この辺りは、今後、運用しながら改善していきたいと考えています。

まとめ

今回は、弊社のフロントエンド開発で使用しているフィーチャーフラグについて紹介させていただきました。 Gitフローからトランクベース開発への変更とともに、リリースサイクルを早めることや、別プロジェクトとのリリースタイミングの連携も取りやすくなりました。

まだまだ改善できる点やこれから出てくる課題もあると思いますが、引き続きよりよい開発ができることを目指していきます。 もしGaudiy に興味を持っていただいた方は、ぜひお気軽にお話ししましょう!

youtrust.jp

gaudiy3.notion.site