مشاركة عبر


طرح الميزات للجماهير المستهدفة في تطبيق Node.js

في هذا الدليل، ستستخدم عامل تصفية الاستهداف لنشر ميزة للجماهير المستهدفة لتطبيق Node.js. لمزيد من المعلومات حول عامل تصفية الاستهداف، راجع طرح الميزات للجماهير المستهدفة.

المتطلبات الأساسية

إنشاء تطبيق ويب مع علامة ميزة

في هذا القسم، يمكنك إنشاء تطبيق ويب يستخدم علامة ميزة Beta للتحكم في الوصول إلى إصدار بيتا من صفحة ويب.

إعداد مشروع 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 App Configuration

  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 App Configuration لتحميل علامات الميزات وتمكين التحديث التلقائي وإنشاء كائن 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 ...

تمكين الاستهداف لتطبيق الويب

مطلوب سياق استهداف عند تقييم الميزات مع تمكين الاستهداف. لتوفير هذا السياق بشكل صريح لتقييم الميزات، يمكنك تمريره كمعلمة 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 إلى نقطة نهاية متجر App Configuration الموجود ضمن نظرة عامة على متجرك في مدخل Microsoft 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، تابع إلى المستند التالي.