共用方式為


在 Node.js 應用程式中向目標受眾推出新功能

在本指南中,您將使用目標篩選將功能推送至 Node.js 應用程式的目標用戶。 如需目標篩選的詳細資訊,請參閱向目標受眾推出功能

先決條件

使用功能旗標建立 Web 應用程式

在本節中,您會建立使用 Beta 功能旗標 來控制網頁 Beta 版存取權的 Web 應用程式。

設定 Node.js Express 專案

  1. 建立名為 targeting-filter-tutorial 的資料夾,並初始化專案。

    mkdir targeting-filter-tutorial
    cd targeting-filter-tutorial
    npm init -y
    
  2. 安裝下列套件。

    npm install @azure/app-configuration-provider
    npm install @microsoft/feature-management
    npm install express
    
  3. 建立名為 app.js 的新檔案,並新增下列程序代碼。

    const express = require("express");
    const server = express();
    const port = "8080";
    
    server.listen(port, () => {
        console.log(`Server is running at http://localhost:${port}`);
    });
    

連接到 Azure 應用程式設定

  1. 更新 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 應用程式組態以載入功能旗標、啟用自動重新整理,以及建立 FeatureManager 物件以供稍後存取功能旗標。 中間件會在每個要求之前新增以重新整理組態。

  2. 更新程式代碼,以確保 Express 伺服器只有在設定成功初始化之後才會啟動。

    // Existing code ...
    initializeConfig()
        .then(() => {
            // Start the express server.
            server.listen(port, () => {
                console.log(`Server is running at http://localhost:${port}`);
            });
        })
    

啟用功能旗標

將下列程式代碼新增至 app.js 檔案,以設定 Express 伺服器的路由處理程式。 伺服器會根據 Beta 功能旗標是否啟用,提供不同的內容。

// 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() 呼叫。

您在本教學課程中使用環境型目標內容。

  1. 在 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 ...
    
  2. 在建構 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}`);
        });
    })

作用中的目標篩選

  1. 將名為 AZURE_APPCONFIG_ENDPOINT 的環境變數設定為在 Azure 入口網站中,於市集的 總覽 底下找到的應用程式組態存放區端點。

    如果您使用 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>'
    
  2. 執行應用程式。

    node app.js
    
  3. 請開啟瀏覽器,然後瀏覽至 localhost:8080。 您應該會看到應用程式的預設檢視。

    應用程式的螢幕快照,其中顯示預設問候語訊息。

    1. 將 新增 userId 為 URL 中的查詢參數,以指定使用者識別碼。 請造訪 localhost:8080/?userId=test@contoso.com。 您會看到 Beta 頁面,因為 test@contoso.com 已指定為目標使用者。

    應用程式的螢幕快照,其中顯示 Beta 頁面。

  4. 請造訪 localhost:8080/?userId=testuser@contoso.com。 您無法看到 Beta 頁面,因為 testuser@contoso.com 已指定為排除的使用者。

    應用程式的螢幕快照,其中顯示預設內容。

後續步驟

若要深入了解功能篩選,請繼續檢視下列文件。

如需 JavaScript 功能管理程式庫的完整功能摘要,請繼續參閱下列文件。