Condividi tramite


Distribuire le funzionalità a un pubblico specifico in un'applicazione Node.js

In questa guida si userà il filtro di destinazione per implementare una funzionalità per i gruppi di destinatari target per l'applicazione Node.js. Per altre informazioni sul filtro di destinazione, vedere Implementare le funzionalità ai gruppi di destinatari target.

Prerequisiti

Creare un'applicazione Web con un flag di funzionalità

In questa sezione viene creata un'applicazione Web che usa il flag di funzionalità Beta per controllare l'accesso alla versione beta di una pagina Web.

Configurare un progetto Node.js Express

  1. Creare una cartella denominata targeting-filter-tutorial e inizializzare il progetto.

    mkdir targeting-filter-tutorial
    cd targeting-filter-tutorial
    npm init -y
    
  2. Installare i pacchetti seguenti.

    npm install @azure/app-configuration-provider
    npm install @microsoft/feature-management
    npm install express
    
  3. Creare un nuovo file denominato app.js e aggiungere il codice seguente.

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

Connettersi ad Azure App Configuration

  1. Aggiornare il app.js e aggiungere il codice seguente.

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

    Connetti ad Azure App Configuration per caricare i flag di funzionalità, abilitare l'aggiornamento automatico e creare un oggetto FeatureManager per accedere ai flag di funzionalità in un secondo momento. Un middleware viene aggiunto alla configurazione di aggiornamento prima di ogni richiesta.

  2. Aggiornare il codice per assicurarsi che il server Express venga avviato solo dopo che la configurazione è stata inizializzata correttamente.

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

Usare il flag di funzionalità

Aggiungere il codice seguente al file app.js per configurare il gestore di route per il server Express. Il server servirà contenuto diverso in base al fatto che il flag di funzionalità beta sia abilitato.

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

Abilitare la selezione dell'applicazione Web come destinazione

Quando si valutano le funzionalità con la destinazione abilitata, è necessario un contesto di destinazione. Per fornire in modo esplicito questo contesto per la valutazione delle funzionalità, è possibile passarlo come parametro al metodo featureManager.isEnabled.

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

In un'applicazione Web, il contesto di destinazione può anche essere fornito come contesto di ambiente implementando l'interfaccia ITargetingContextAccessor . Un contesto di targeting ambientale significa che le informazioni di targeting vengono recuperate automaticamente dall'ambiente, come ad esempio la richiesta HTTP corrente, senza doverle passare in modo esplicito a ciascuna chiamata featureManager.isEnabled().

In questa esercitazione si usa il contesto di destinazione ambientale.

  1. Aggiungere il codice seguente dopo la dichiarazione del server Express. Usa AsyncLocalStorage per archiviare la richiesta corrente, consentendo al gestore delle funzionalità di recuperare automaticamente il contesto di destinazione tramite callback della funzione di accesso al contesto di destinazione. Per altri dettagli, vedere Uso di AsyncLocalStorage per il contesto della richiesta.

    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. Quando si costruisce FeatureManager, passare la funzione di accesso del contesto di destinazione a FeatureManagerOptions.

    featureManager = new FeatureManager(
        new ConfigurationMapFeatureFlagProvider(appConfig),
        {
            targetingContextAccessor: targetingContextAccessor
        });
    

Dopo aver completato i passaggi precedenti, il file diapp.js dovrebbe ora contenere l'implementazione completa seguente.

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}`);
        });
    })

Filtro di destinazione in azione

  1. Impostare la variabile di ambiente denominata AZURE_APPCONFIG_ENDPOINT sull'endpoint dell'archivio di Configurazione app disponibile in Panoramica dello store nel portale di Azure.

    Se si usa il prompt dei comandi di Windows, eseguire il comando seguente e riavviare il prompt per rendere effettiva la modifica:

    setx AZURE_APPCONFIG_ENDPOINT "<endpoint-of-your-app-configuration-store>"
    

    Se si usa PowerShell, eseguire il comando seguente:

    $Env:AZURE_APPCONFIG_ENDPOINT = "<endpoint-of-your-app-configuration-store>"
    

    Se si usa macOS o Linux, eseguire il comando seguente:

    export AZURE_APPCONFIG_ENDPOINT='<endpoint-of-your-app-configuration-store>'
    
  2. Eseguire l'applicazione.

    node app.js
    
  3. Aprire il browser e passare a localhost:8080. Verrà visualizzata la visualizzazione predefinita dell'app.

    Screenshot dell'app, che mostra il messaggio di saluto predefinito.

    1. Aggiungere userId come parametro di query nell'URL per specificare l'ID utente. Visitare localhost:8080/?userId=test@contoso.com. Viene visualizzata la pagina beta, perché test@contoso.com è specificato come utente target.

    Screenshot dell'app, che mostra la pagina beta.

  4. Visitare localhost:8080/?userId=testuser@contoso.com. Non è possibile visualizzare la pagina beta perché testuser@contoso.com è specificata come utente escluso.

    Screenshot dell'app, che mostra il contenuto predefinito.

Passaggi successivi

Per altre informazioni sui filtri delle funzionalità, continuare con i documenti seguenti.

Per il rundown completo delle funzionalità della libreria di gestione delle funzionalità JavaScript, continuare con il documento seguente.