Поделиться через


Внедрение функций для определённых аудиторий в приложении Node.js

В этом руководстве вы будете использовать фильтр таргетинга, чтобы включить функцию для целевой аудитории вашего приложения Node.js. Дополнительные сведения о фильтре целевого назначения см. в статье "Развертывание функций для целевых аудиторий".

Предпосылки

Создание веб-приложения с флагом компонента

В этом разделе описано, как создать веб-приложение, использующее флаг бета-функции для управления доступом к бета-версии веб-страницы.

Настройте проект 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. Сервер будет обслуживать разное содержимое в зависимости от того, включен ли флаг функции бета-версии .

// 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 ...

Включение целевого объекта для веб-приложения

Контекст таргетинга требуется при анализе функций с включенным таргетингом. Чтобы явно предоставить этот контекст для оценки признаков, его можно передать в качестве параметра методу featureManager.isEnabled .

const isBetaEnabled = await featureManager.isEnabled("Beta", { userId: "UserA", groups: ["Group1"] });

В веб-приложении контекст целевого объекта можно также предоставить в качестве внешнего контекста, реализуя интерфейс 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. Вы видите бета-страницу, потому что test@contoso.com указан в качестве целевого пользователя.

    Снимок экрана: приложение с бета-страницей.

  4. Посетите localhost:8080/?userId=testuser@contoso.com. Не удается увидеть бета-страницу, так как testuser@contoso.com указан как исключенный пользователь.

    Снимок экрана: приложение с содержимым по умолчанию.

Дальнейшие шаги

Дополнительные сведения о фильтрах функций см. в следующих документах.

Для полного запуска функции библиотеки функций JavaScript перейдите к следующему документу.