STORES Product Blog

こだわりを持ったお商売を支える「STORES」のテクノロジー部門のメンバーによるブログです。

STORES のリリーストグル基盤を作りました

STORES のykpythemindです。

STORES 株式会社 は25年3月末に、店鋪運営に必要な7サービスをまとめた新プランを低価格でリリースしました。

店鋪のためのレジ・キャッシュレス決済・ネットショップ・予約・会員管理システムなどをまとめて月額3300円で利用できるとても魅力的なプランになっています。サービスサイトはこちら。

さて、今回はこのリリースの裏側で自作のリリーストグルの仕組みを導入していました。STORES のtoggleで、stoggle (エストグル)と言います。

企画

我々は複数のプロダクトを統合して、より大きな価値を提供したいと考えています。

product.st.inc

リリーストグル的な仕組みは各地に点在しているものの、システムをまたいで(STORES グローバルで) オンオフする統一された方法はありませんでした。 運良く自分が社内の様々なユースケースを知っており、それを元にコンセプトを作りました

社内のドキュメントにまとめた諸々

最終的には以下のような仕様になっています

  • stoggleがSTORES 内のシステムに提供するのは https://{stoggleのドメイン}/toggles/{toggleKey} というエンドポイントのみ。これはトグルがオンかオフかのjsonを返すので、各システムはこれを利用する。
  • toggleKeyは {featureId}::{target} というフォーマットで記述されている。
  • featureIdは機能。たとえば、新しい分析機能をオンにする、とか。このfeatureIdはあらかじめ登録しておく。
  • targetはその機能を誰に有効化するかどうか。ログインしているアカウントIDでも、テナントIDでも良い。
  • 社内の管理画面からtoggleKeyを追加することで、リリースより前に社内の人が機能を使えるようになる
  • ALLというtargetを追加すると対象の機能がリリースできる (どのクエリもオンとして返るようになります)

アプリケーション側では、例えば次のように書くことで特定の機能 (例ではpost_renewal_2025) が有効かどうかの分岐を入れることができます。

class PostsController < ApplicationController
  before_action :redirect_to_new_feature_page

  def index; end

  private

  def redirect_to_new_feature_page
    resp = Net::HTTP.get("https://stoggle.example.com/toggles/post_renewal_2025::#{current_user.email}")
    if JSON.parse(resp.body)["enabled"]
      redirect_to ...
    end
  end
end

実装

stoggleのエンドポイントは AWS Lambda + Dynamo DB で実現しています。

管理画面は nginx_omniauth_adapter を利用した社内認証システムを通じて認証されています。viteでビルドした管理画面のアセットを含めて lambroll でデプロイする構成になっています。

管理画面。有効にしているトグルが並んでいる

Dynamo DBで効率的なクエリにするために管理画面上からはfeatureIDとtargetを非正規化して保存するのが工夫ポイントです。

const toggleKey = `${body.featureId}::${body.target}`;

// toggleKeyによって upsert の挙動になる
await dynamo.send(
  new PutCommand({
    TableName: tableName,
    Item: {
      toggleKey: toggleKey,
      featureId: body.featureId,
      note: body.note,
      disabled: body.disabled || false,
      createdAt: current.Item?.createdAt ?? new Date().toISOString(),
    },
  })
);

stoggleは導入の障壁が限りなく低いように作られており、今年の2月から4月までで15を超えるトグルが利用され、機能のリリースされています。また、1日数百円程度の低コストで運用されています。

デザイン

AWS App Config Feature Flag のような高機能な仕組みを検討したこともありますが、stoggleは恥ずかしいくらいシンプルな設計をこだわっています。

AWS AppConfig Feature Flagの様子。ルールに式が書けてすごいが、ソフトウェアエンジニアにとっても難しい

stoggleは社内のプロダクトマネージャやセールス、CSの方々にも前もって使っていただけるようなものにしています。 (実際に機能リリース前に機能検証していただいています)

機能を数%ずつ開放するような段階的ロールアウトの機能の要望をいただくこともありますが、現時点では実装しない意思決定をしています。リリース時間が伸びるとそれはそれで新旧の振る舞いを考慮する複雑さが増えますし、今のSTORES の開発体制では不要と考えています。*1

また、センシティブな情報が取得できるものでもないため、認証のためのAPIキーの用意や設定も不要です。

よもやま話

stoggleはシンプルなシステムになっていて、技術的に難しいことは一切していません。
しかしソフトウェアのデザインとして上記のようなこだわりがあったり、STORESのエンジニアが利活用していて、勝手にコミットしてくれて育っており、愛着のわくソフトになっていて、良いと思うんですよね。

呼び方の議論、ちなみに今はどちらも公式な呼び名になっています

js版のsdkが突如導入された

内定者バイトのsushichan。ありがとう

トグルの追加。社内のメールアドレスのみ特殊な記法が使えて、気にいっている機能の1つ

3月のリリースについての話はこれからしていけたらと思います。それではまた。

*1: 段階的なロールアウトが必要であれば各アプリケーションDBにトグルレコードを作る形を取っています