Partager via


Tutoriel : Utiliser des indicateurs de fonctionnalité variant dans une application Node.js

Dans ce tutoriel, vous utilisez un indicateur de fonctionnalité variant pour gérer les expériences pour différents segments d’utilisateurs dans un exemple d’application, Citation du jour. Vous utilisez l’indicateur de fonctionnalité variant créé dans Utiliser des indicateurs de fonctionnalité variant. Avant de continuer, veillez à créer l’indicateur de fonctionnalité variant nommé Salutations dans votre magasin App Configuration.

Conditions préalables

Création d’une application Node.js

  1. Créez un dossier appelé quote-of-the-day et initialisez le projet.

    mkdir quote-of-the-day
    cd quote-of-the-day
    npm init -y
    
  2. Installez les packages suivants :

    npm install @azure/app-configuration-provider
    npm install @microsoft/feature-management
    npm install express
    
  3. Créez un fichier nommé server.js et ajoutez le code suivant.

    const express = require("express");
    const server = express();
    
    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() {
        appConfig = await load(appConfigEndpoint, new DefaultAzureCredential(), {
            featureFlagOptions: {
                enabled: true,
                refresh: {
                    enabled: true
                }
            }
        });
    
        const featureFlagProvider = new ConfigurationMapFeatureFlagProvider(appConfig);
        featureManager = new FeatureManager(featureFlagProvider);
    }
    
    function startServer() {
        // Use a middleware to refresh the configuration before each request
        server.use((req, res, next) => {
            appConfig.refresh();
            next();
        });
        server.use(express.json());
        // Serve static index.html from the current folder
        server.use(express.static("."));
    
        // This API returns the different greeting messages based on the segment the user belongs to.
        // It evaluates a variant feature flag based on user context. The greeting message is retrieved from the variant configuration.
        server.get("/api/getGreetingMessage", async (req, res) => {
            const { userId, groups } = req.query;
            const variant = await featureManager.getVariant("Greeting", { userId: userId, groups: groups ? groups.split(",") : [] });
            res.status(200).send({ message: variant?.configuration });
        });
    
        server.post("/api/like", (req, res) => {
            const { UserId } = req.body;
            if (UserId === undefined) {
                return res.status(400).send({ error: "UserId is required" });
            }
            // Here you would typically emit a 'like' event to compare variants.
            res.status(200).send();
        });
    
        const port = "8080";
        server.listen(port, () => {
            console.log(`Server is running at http://localhost:${port}`);
        });
    }
    
    // Initialize the configuration and start the server
    initializeConfig()
        .then(() => {
            startServer();
        })
        .catch((error) => {
            console.error("Failed to load configuration:", error);
            process.exit(1);
        });
    
  4. Créez un fichier nommé index.html et ajoutez le code suivant :

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Quote of the Day</title>
    <style>
        .heart-button {
        background-color: transparent;
        border: none;
        cursor: pointer;
        font-size: 24px;
        }
    
        .heart-button:hover {
        background-color: #F0F0F0;
        }
    </style>
    </head>
    <body>
    <div style="display: flex; flex-direction: column; min-height: 100vh; background-color: #f4f4f4;">
        <header style="background-color: white; border-bottom: 1px solid #eaeaea; display: flex; justify-content: space-between; align-items: center; font-family: 'Arial', sans-serif; font-size: 16px;">
        <div style="font-size: 1.25em; color: black;">QuoteOfTheDay</div>
        </header>
    
        <main style="display: flex; justify-content: center; align-items: center; flex-grow: 1;">
        <div style="background-color: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); max-width: 700px; position: relative; text-align: left;">
            <div id="quote-content">
            <h2 id="greeting">Quote of the Day</h2>
            <blockquote style="font-size: 2em; font-style: italic; color: #4EC2F7; margin: 0 0 20px 0; line-height: 1.4;">
                <p>"You cannot change what you are, only what you do."</p>
                <footer style="font-size: 0.55em; color: black; font-family: 'Arial', sans-serif; font-style: normal; font-weight: bold;">— Philip Pullman</footer>
            </blockquote>
            <div style="position: absolute; top: 10px; right: 10px; display: flex;">
                <button class="heart-button" id="like-button">
                <span id="heart-icon" style="color: #ccc">♥</span>
                </button>
            </div>
            </div>
            <div id="loading" style="display: none;">
            <p>Loading</p>
            </div>
        </div>
        </main>
    </div>
    
    <script>
        // extract URL parameters to simulate user login
        document.addEventListener('DOMContentLoaded', function() {
        const urlParams = new URLSearchParams(window.location.search);
        const currentUser = urlParams.get('userId') || '';
        let liked = false;
    
        const greetingElement = document.getElementById('greeting');
        const heartIcon = document.getElementById('heart-icon');
        const likeButton = document.getElementById('like-button');
        const quoteContent = document.getElementById('quote-content');
        const loadingElement = document.getElementById('loading');
    
        async function init() {
            quoteContent.style.display = 'none';
            loadingElement.style.display = 'block';
    
            const response = await fetch(`/api/getGreetingMessage?userId=${currentUser}`, { 
            method: "GET"
            });
            const result = await response.json();
            greetingElement.textContent = result.message || "";
            quoteContent.style.display = 'block';
            loadingElement.style.display = 'none';
        }
    
        likeButton.addEventListener('click', async function() {
            if (!liked) {
            const response = await fetch("/api/like", { 
                method: "POST", 
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ UserId: currentUser }),
            });
            }
            liked = !liked;
            heartIcon.style.color = liked ? 'red' : '#ccc';
        });
    
        init();
        });
    </script>
    </body>
    </html>
    

    Par souci de simplicité, l’exemple extrait les userId paramètres de requête d’URL (par exemple ?userId=UserA) pour simuler différentes identités utilisateur.

Exécuter l’application

  1. Définissez la variable d’environnement nommée AZURE_APPCONFIG_ENDPOINT sur le point de terminaison de votre magasin App Configuration qui se trouve sous la Vue d’ensemble de votre magasin dans le Portail Azure.

    Si vous utilisez l’invite de commandes Windows, exécutez la commande suivante et redémarrez l’invite pour que la modification soit prise en compte :

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

    Si vous utilisez PowerShell, exécutez la commande suivante :

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

    Si vous utilisez macOS ou Linux, exécutez la commande suivante :

    export AZURE_APPCONFIG_ENDPOINT='<endpoint-of-your-app-configuration-store>'
    
  2. Exécutez l’application.

    node server.js
    
  3. Ouvrez votre navigateur et accédez à localhost:8080. Vous devez voir l’affichage par défaut de l’application qui n’a pas de message d’accueil.

    Capture d’écran de l’application Quote of the day, montrant aucun message d’accueil pour l’utilisateur.

  4. Vous pouvez utiliser userId le paramètre de requête dans l’URL pour spécifier l’ID utilisateur. Visitez localhost:8080/?userId=UserA et vous voyez un long message d'accueil.

    Capture d’écran de l’application Quote of the day, montrant un message d’accueil long pour l’utilisateur.

  5. Essayez différents ID d’utilisateur pour voir comment l’indicateur de fonctionnalité variant modifie le message d’accueil pour différents segments d’utilisateurs. Visiter localhost:8080/?userId=UserB et vous voyez un message d’accueil plus court.

    Capture d’écran de l’application Quote of the day, montrant un message d’accueil simple pour l’utilisateur.

Étapes suivantes

Pour connaître l’exécution complète des fonctionnalités de la bibliothèque de gestion des fonctionnalités JavaScript, reportez-vous au document suivant.