このガイドでは、ターゲット フィルターを使用して、Node.js アプリケーションの対象ユーザーに機能をロールアウトします。 ターゲット フィルターの詳細については、「対象ユーザーに対して機能をロールアウトする」を参照してください。
[前提条件]
- アクティブなサブスクリプションを持つ Azure アカウント。 無料で作成できます。
- "App Configuration ストアは、ストアを作成するためのチュートリアルに示されているように設置されています。"
- ターゲット フィルターを含む ベータ 機能フラグ。 機能フラグを使用する。
- Node.jsの LTS バージョン 。
機能フラグを使用する Web アプリケーションを作成する
このセクションでは、 ベータ 機能フラグ を使用して、Web ページのベータ版へのアクセスを制御する Web アプリケーションを作成します。
Node.js Express プロジェクトを設定する
targeting-filter-tutorialという名前のフォルダーを作成し、プロジェクトを初期化します。mkdir targeting-filter-tutorial cd targeting-filter-tutorial npm init -y次のパッケージをインストールしてください。
npm install @azure/app-configuration-provider npm install @microsoft/feature-management npm install expressapp.jsという名前 の 新しいファイルを作成し、次のコードを追加します。
const express = require("express"); const server = express(); const port = "8080"; server.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); });
Azure App Configuration に接続する
app.js を更新し、次のコードを追加します。
// Existing code ... const appConfigEndpoint = process.env.AZURE_APPCONFIG_ENDPOINT; const { DefaultAzureCredential } = require("@azure/identity"); const { load } = require("@azure/app-configuration-provider"); const { FeatureManager, ConfigurationMapFeatureFlagProvider } = require("@microsoft/feature-management"); let appConfig; let featureManager; async function initializeConfig() { // Load feature flags from App Configuration. appConfig = await load(appConfigEndpoint, new DefaultAzureCredential(), { featureFlagOptions: { enabled: true, refresh: { enabled: true } } }); // Create feature manager with feature flag provider that accesses feature flags from App Configuration. featureManager = new FeatureManager( new ConfigurationMapFeatureFlagProvider(appConfig)); } // Use a middleware to refresh the configuration before each request. server.use((req, res, next) => { appConfig.refresh(); next(); }); // Existing code ...Azure App Configuration に接続して機能フラグを読み込み、自動更新を有効にして、後で機能フラグにアクセスするための
FeatureManagerオブジェクトを作成します。 ミドルウェアは、各要求の前に構成を更新するために追加されます。構成が正常に初期化された後にのみ Express サーバーが起動するようにコードを更新します。
// Existing code ... initializeConfig() .then(() => { // Start the express server. server.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); })
機能フラグを使用する
次のコードを app.js ファイルに追加して、Express サーバーのルート ハンドラーを構成します。 サーバーは、 ベータ 機能フラグが有効になっているかどうかに基づいて、異なるコンテンツを提供します。
// Existing code ...
server.get("/", async (req, res) => {
const isBetaEnabled = await featureManager.isEnabled("Beta");
const [title, message] = isBetaEnabled
? ["Beta Page", "This is a beta page."]
: ["Home Page", "Welcome."];
res.send(
`<!DOCTYPE html>
<html>
<head><title>${title}</title></head>
<body style="display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0;">
<h1 style="text-align: center; font-size: 5rem;">${message}</h1>
</body>
</html>`
);
});
initializeConfig()
// Existing code ...
Web アプリケーションのターゲット設定を有効にする
ターゲット設定が有効になっている機能を評価する場合は、ターゲット コンテキストが必要です。 このコンテキストを特徴評価用に明示的に提供するには、パラメーターとして featureManager.isEnabled メソッドに渡します。
const isBetaEnabled = await featureManager.isEnabled("Beta", { userId: "UserA", groups: ["Group1"] });
Web アプリケーションでは、 ITargetingContextAccessor インターフェイスを実装することで、ターゲット コンテキストをアンビエント コンテキストとして提供することもできます。 アンビエント ターゲット コンテキストとは、ターゲット情報が、現在の HTTP 要求などの環境から自動的に取得されることを意味し、各 featureManager.isEnabled() 呼び出しに明示的に渡す必要はありません。
このチュートリアルでは、アンビエント ターゲット コンテキストを使用します。
Express サーバー宣言の後に次のコードを追加します。
AsyncLocalStorageを使用して現在の要求を格納し、機能マネージャーがターゲット コンテキスト アクセサー コールバックを介してターゲット コンテキストを自動的に取得できるようにします。 詳細については、 要求コンテキストでの AsyncLocalStorage の使用に関するページを参照してください。const express = require("express"); const server = express(); const port = 8080; const { AsyncLocalStorage } = require("async_hooks"); const requestAccessor = new AsyncLocalStorage(); // Use a middleware to store request context. server.use((req, res, next) => { // Store the request in AsyncLocalStorage for this request chain. requestAccessor.run(req, () => { next(); }); }); // Create a targeting context accessor that retrieves user data from the current request. const targetingContextAccessor = { getTargetingContext: () => { // Get the current request from AsyncLocalStorage. const request = requestAccessor.getStore(); if (!request) { return undefined; } const { userId, groups } = request.query; return { userId: userId, groups: groups ? groups.split(",") : [] }; } }; // Existing code ...FeatureManagerを構築するときは、ターゲット コンテキスト アクセサーをFeatureManagerOptionsに渡します。featureManager = new FeatureManager( new ConfigurationMapFeatureFlagProvider(appConfig), { targetingContextAccessor: targetingContextAccessor });
前の手順を完了すると、 app.js ファイルに次の完全な実装が含まれるようになります。
const express = require("express");
const server = express();
const port = 8080;
const { AsyncLocalStorage } = require("async_hooks");
const requestAccessor = new AsyncLocalStorage();
// Use a middleware to store request context
server.use((req, res, next) => {
// Store the request in AsyncLocalStorage for this request chain
requestAccessor.run(req, () => {
next();
});
});
// Create a targeting context accessor that retrieves user data from the current request
const targetingContextAccessor = {
getTargetingContext: () => {
// Get the current request from AsyncLocalStorage
const request = requestAccessor.getStore();
if (!request) {
return undefined;
}
const { userId, groups } = request.query;
return {
userId: userId,
groups: groups ? groups.split(",") : []
};
}
};
const appConfigEndpoint = process.env.AZURE_APPCONFIG_ENDPOINT;
const { DefaultAzureCredential } = require("@azure/identity");
const { load } = require("@azure/app-configuration-provider");
const { FeatureManager, ConfigurationMapFeatureFlagProvider } = require("@microsoft/feature-management");
let appConfig;
let featureManager;
async function initializeConfig() {
// Load feature flags from App Configuration.
appConfig = await load(appConfigEndpoint, new DefaultAzureCredential(), {
featureFlagOptions: {
enabled: true,
refresh: {
enabled: true
}
}
});
// Create feature manager with feature flag provider that accesses feature flags from App Configuration and targeting context accessor.
featureManager = new FeatureManager(
new ConfigurationMapFeatureFlagProvider(appConfig),
{
targetingContextAccessor: targetingContextAccessor
});
}
// Use a middleware to refresh the configuration before each request
server.use((req, res, next) => {
appConfig.refresh();
next();
});
server.get("/", async (req, res) => {
const isBetaEnabled = await featureManager.isEnabled("Beta");
const [title, message] = isBetaEnabled
? ["Beta Page", "This is a beta page."]
: ["Home Page", "Welcome."];
res.send(
`<!DOCTYPE html>
<html>
<head><title>${title}</title></head>
<body style="display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0;">
<h1 style="text-align: center; font-size: 5rem;">${message}</h1>
</body>
</html>`
);
});
// Initialize the configuration and start the server
initializeConfig()
.then(() => {
// Start the express server.
server.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
})
ターゲット フィルターの動作
AZURE_APPCONFIG_ENDPOINTという名前の環境変数を、Azure portal のストアの概要にある App Configuration ストアのエンドポイントに設定します。
Windows コマンド プロンプトを使用する場合は、次のコマンドを実行してコマンド プロンプトを再起動し、変更が反映されるようにします。
setx AZURE_APPCONFIG_ENDPOINT "<endpoint-of-your-app-configuration-store>"PowerShell を使用する場合は、次のコマンドを実行します。
$Env:AZURE_APPCONFIG_ENDPOINT = "<endpoint-of-your-app-configuration-store>"macOS または Linux を使用する場合は、次のコマンドを実行します。
export AZURE_APPCONFIG_ENDPOINT='<endpoint-of-your-app-configuration-store>'アプリケーションを実行します。
node app.jsブラウザーを開き、
localhost:8080に移動します。 アプリの既定のビューが表示されます。
-
- URL にクエリ パラメーターとして
userIdを追加して、ユーザー ID を指定します。localhost:8080/?userId=test@contoso.comを訪問. ターゲット ユーザーとしてtest@contoso.comが指定されているため、ベータ 版ページが表示されます。
- URL にクエリ パラメーターとして
localhost:8080/?userId=testuser@contoso.comを訪問.testuser@contoso.comは除外されたユーザーとして指定されているため、ベータ 版ページを表示できません。
次のステップ
機能フィルターについてさらに学ぶには、次のドキュメントに進んでください。
JavaScript 機能管理ライブラリの詳細な機能の説明については、次のドキュメントに進んでください。