Anmerkung
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die JavaScript-Featureverwaltungsbibliothek bietet eine Möglichkeit, Anwendungsfunktionen basierend auf Featureflags zu entwickeln und verfügbar zu machen. Sobald ein neues Feature entwickelt wurde, haben viele Anwendungen spezielle Anforderungen, z. B. wann das Feature aktiviert werden soll und unter welchen Bedingungen. Diese Bibliothek bietet eine Möglichkeit, diese Beziehungen zu definieren und auch in gängige JavaScript-Codemuster zu integrieren, um diese Features verfügbar zu machen.
Featureflags bieten eine Möglichkeit für JavaScript-Anwendungen, Features dynamisch zu aktivieren oder zu deaktivieren. Entwickler können Featureflags in einfachen Anwendungsfällen wie Bedingungsanweisungen verwenden.
Hier sind einige der Vorteile der Verwendung der JavaScript-Featureverwaltungsbibliothek:
- Eine allgemeine Konvention für die Featureverwaltung
- Niedrige Einstiegsbarriere
- Unterstützt JSON-Objekte und kartenbasierte Feature-Flag-Quellen
- Unterstützt die Verwendung in Node.js und Browserumgebungen.
- Verwaltung der Featureflaglebensdauer mit Azure App Configuration
- Konfigurationswerte können sich in Echtzeit ändern
- Behandlung einfacher bis komplexer Szenarien
- Aktivieren/Deaktivieren von Features durch deklarative Konfigurationsdatei
- Dynamische Auswertung des Funktionsstatus basierend auf dem Aufruf an den Server
Die JavaScript-Featureverwaltungsbibliothek ist Open Source. Weitere Informationen finden Sie im GitHub-Repository.
Hinweis
Es wird empfohlen, die Featureverwaltungsbibliothek zusammen mit Azure App Configuration zu verwenden. Azure App Configuration bietet eine Lösung zur zentralen Verwaltung von Anwendungseinstellungen und Featureflags. Weitere Details finden Sie in diesem Abschnitt.
Featureflags
Featurekennzeichnungen bestehen aus zwei Teilen, einem Namen und einer Liste von Featurefiltern, die zum Aktivieren des Features verwendet werden.
Featurefilter
Featurefilter definieren ein Szenario, für das ein Feature aktiviert werden soll. Wenn ein Feature ausgewertet wird, egal ob es aktiviert oder deaktiviert ist, wird die Liste der Featurefilter durchlaufen, bis einer der Filter entscheidet, dass das Feature aktiviert werden soll. An diesem Punkt gilt das Feature als aktiviert, und der Durchlauf der Featurefilter endet. Wenn kein Featurefilter angibt, dass das Feature aktiviert werden soll, gilt es als deaktiviert.
Beispielsweise könnte ein Microsoft Edge-Browserfeaturefilter entworfen werden. Dieser Featurefilter aktiviert alle daran angefügten Features, solange eine HTTP-Anforderung von Microsoft Edge stammt.
Featureflagkonfiguration
In JavaScript verwenden Entwickler häufig Objekte oder Maps als primäre Datenstrukturen, um Konfigurationen darzustellen. Die JavaScript-Featureverwaltungsbibliothek unterstützt beide Konfigurationsansätze und bietet Entwicklern die Flexibilität, die Option auszuwählen, die ihren Anforderungen am besten entspricht.
FeatureManager kann Featureflags aus verschiedenen Konfigurationstypen mithilfe der integrierten Elemente ConfigurationObjectFeatureFlagProvider und ConfigurationMapFeatureFlagProvider lesen.
const config = new Map([
["feature_management", {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true
},
{
"id": "FeatureU",
"enabled": false
}
]
}],
["some other configuration", " some value"]
]);
import { ConfigurationMapFeatureFlagProvider, FeatureManager } from "@microsoft/feature-management";
const featureProvider = new ConfigurationMapFeatureFlagProvider(config);
const featureManager = new FeatureManager(featureProvider);
Verwenden Sie Feature-Flags aus Azure App Configuration
Featureflags sollten sich außerhalb der Anwendung befinden und separat verwaltet werden, anstatt sie in Ihrer Anwendung hart zu codieren. Dadurch können Sie Flagzustände jederzeit ändern, und die Änderungen werden in der Anwendung sofort wirksam. Der Azure App Configuration-Dienst bietet eine dedizierte Portalbenutzeroberfläche, über die Sie alle Ihre Featureflags verwalten können. Weitere Informationen finden Sie im Tutorial.
Darüber hinaus übermittelt der Azure App Configuration-Dienst die Featureflags unter Verwendung der zugehörigen JavaScript-Clientbibliothek @azure/app-configuration-provider direkt an Ihre Anwendung. Das folgende Beispiel zeigt die Verwendung der Bibliothek.
Der App Configuration JavaScript-Anbieter stellt Featureflags in einem Map-Objekt bereit. Das integrierte Element ConfigurationMapFeatureFlagProvider hilft in diesem Fall dabei, Featureflags zu laden.
import { DefaultAzureCredential } from "@azure/identity";
import { load } from "@azure/app-configuration-provider";
import { ConfigurationMapFeatureFlagProvider, FeatureManager } from "@microsoft/feature-management";
const appConfig = await load("YOUR_APP-CONFIG-ENDPOINT",
new DefaultAzureCredential(), // For more information: https://learn.microsoft.com/javascript/api/overview/azure/identity-readme
{ featureFlagOptions: { enabled: true } }); // load feature flags from Azure App Configuration service
const featureProvider = new ConfigurationMapFeatureFlagProvider(appConfig);
const featureManager = new FeatureManager(featureProvider);
Verwenden Sie Azure App Configuration, um den Status des Feature-Flags dynamisch zu steuern.
Die Azure App-Konfiguration ist nicht nur eine Lösung zum Externalisieren des Speichers und der zentralen Verwaltung Ihrer Featurekennzeichnungen, sondern ermöglicht es Ihnen auch, die Featurekennzeichnungen dynamisch zu aktivieren/zu deaktivieren.
Um die dynamische Aktualisierung für Featurekennzeichnungen zu aktivieren, müssen Sie die refresh-Eigenschaft der featureFlagOptions beim Laden von Featurekennzeichnungen aus der Azure App-Konfiguration konfigurieren.
const appConfig = await load("YOUR_APP-CONFIG-ENDPOINT", new DefaultAzureCredential(), {
featureFlagOptions: {
enabled: true,
refresh: {
enabled: true, // enable the dynamic refresh for feature flags
refreshIntervalInMs: 30_000
}
}
});
const featureProvider = new ConfigurationMapFeatureFlagProvider(appConfig);
const featureManager = new FeatureManager(featureProvider);
Sie müssen die refresh Methode aufrufen, um den status der neuesten Featurekennzeichnung abzurufen.
await appConfig.refresh(); // Refresh to get the latest feature flags
const isBetaEnabled = await featureManager.isEnabled("Beta");
console.log(`Beta is enabled: ${isBetaEnabled}`);
Hinweis
Weitere Informationen zur Verwendung der Featureverwaltungsbibliothek mit Azure App Configuration finden Sie unter Schnellstart.
Featureflagdeklaration
Das folgende Beispiel zeigt das Format, das zum Einrichten von Featureflags in einer JSON-Datei verwendet wird.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true
},
{
"id": "FeatureU",
"enabled": false
},
{
"id": "FeatureV",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
}
]
}
}
Der feature_management-Abschnitt wird konventionell zum Laden von Feature-Flag-Einstellungen verwendet. Der Abschnitt feature_flags ist eine Liste der Featureflags, die in die Bibliothek geladen werden. Im Abschnitt oben sehen wir drei verschiedene Features. Features definieren ihre Featurefilter mithilfe der client_filters-Eigenschaft in conditions. In den Featurefiltern für FeatureT sehen wir, dass enabled ohne definierte Filter true ist, was dazu führt, dass FeatureT immer true zurückgibt.
FeatureU ist identisch mit FeatureT, aber mit enabled gleich false, was dazu führt, dass das Feature immer false zurückgibt.
FeatureV gibt einen Featurefilter mit dem Namen Microsoft.TimeWindow an.
FeatureV ist ein Beispiel für einen konfigurierbaren Featurefilter. Wir können im Beispiel sehen, dass der Filter über eine parameters-Eigenschaft verfügt. Die Eigenschaft parameters wird verwendet, um den Filter zu konfigurieren. In diesem Fall werden die Start- und Endzeiten für das zu aktive Feature konfiguriert.
Das detaillierte Schema des feature_management-Abschnitts finden Sie hier.
Erweitert: Die Verwendung des Doppelpunkts ":" ist in Featurekennzeichnungsnamen verboten.
Anforderungstyp
Die requirement_type-Eigenschaft einer Featurekennzeichnung wird verwendet, um zu bestimmen, ob die Filter Any- oder All-Logik zum Auswerten des Status eines Features verwenden sollen. Wenn requirement_type nicht angegeben ist, wird der Standardwert Any.
-
Anybedeutet, dass nur ein Filter als „true“ ausgewertet werden muss, damit das Feature aktiviert wird. -
Allbedeutet, dass jeder Filter als „true“ ausgewertet werden muss, damit das Feature aktiviert wird.
Der Anforderungstyp (requirement_type) All ändert den Durchlauf. Wenn keine Filter vorhanden sind, ist das Feature deaktiviert. Anschließend werden die Featurefilter durchlaufen, bis einer der Filter entscheidet, dass das Feature deaktiviert werden soll. Wenn kein Filter angibt, dass das Feature deaktiviert werden soll, wird es als aktiviert betrachtet.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureW",
"enabled": true,
"conditions": {
"requirement_type": "All",
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
},
{
"name": "Percentage",
"parameters": {
"Value": "50"
}
}
]
}
},
]
}
}
Im obigen Beispiel gibt FeatureW eine requirement_type von All an, was bedeutet, dass alle Filter als „true“ ausgewertet werden müssen, damit das Feature aktiviert werden kann. In diesem Fall ist das Feature für 50 % der Benutzer im angegebenen Zeitfenster aktiviert.
Verbrauch
Die grundlegende Form der Featureverwaltung überprüft, ob eine Featurekennzeichnung aktiviert ist und führt dann Aktionen basierend auf dem Ergebnis aus. Der Status eines Feature-Flags wird über die Methode FeatureManager von isEnabled überprüft.
import { ConfigurationMapFeatureFlagProvider, FeatureManager } from "@microsoft/feature-management";
const featureProvider = new ConfigurationMapFeatureFlagProvider(config);
const featureManager = new FeatureManager(featureProvider);
const isBetaEnabled = await featureManager.isEnabled("Beta");
if (isBetaEnabled) {
// Do something
}
Implementieren eines Featurefilters
Das Erstellen eines Featurefilters bietet eine Möglichkeit, Features basierend auf von Ihnen definierten Kriterien zu aktivieren. Um einen Featurefilter zu implementieren, muss die IFeatureFilter-Schnittstelle implementiert werden.
IFeatureFilter hat eine name-Eigenschaft und eine Methode namens evaluate.
name sollte in der Konfiguration verwendet werden, um auf den Featurefilter in einem Featureflag zu verweisen. Wenn ein Feature angibt, dass es für einen Featurefilter aktiviert werden kann, wird die evaluate-Methode aufgerufen. Wenn evaluatetrue zurückgibt, bedeutet dies, dass die Funktion aktiviert werden sollte.
interface IFeatureFilter {
name: string;
evaluate(context: IFeatureFilterEvaluationContext, appContext?: unknown): boolean | Promise<boolean>;
}
Der folgende Codeausschnitt veranschaulicht das Implementieren eines benutzerdefinierten Featurefilters mit dem Namen MyCriteria.
class MyCriteriaFilter {
name = "MyCriteria";
evaluate(context, appContext) {
if (satisfyCriteria()) {
return true;
}
else {
return false;
}
}
}
Es wird benötigt, den benutzerdefinierten Filter unter der customFilters Eigenschaft des FeatureManagerOptions Objekts zu registrieren, das an den FeatureManager Konstruktor übergeben wird.
const featureManager = new FeatureManager(ffProvider, {
customFilters: [
new MyCriteriaFilter() // add custom feature filters under FeatureManagerOptions.customFilters
]
});
Parametrisierte Merkmalfilter
Einige Featurefilter erfordern Parameter, um zu entscheiden, ob ein Feature aktiviert werden soll oder nicht. Beispielsweise kann ein Browserfeaturefilter ein Feature für eine bestimmte Gruppe von Browsern aktivieren. Es kann gewünscht werden, dass Edge- und Chrome-Browser ein Feature aktivieren, aber nicht Firefox. Dazu kann ein Featurefilter so konzipiert werden, dass Parameter erwartet werden. Diese Parameter werden in der Featurekonfiguration angegeben, und im Code kann über den IFeatureFilterEvaluationContext-Parameter von IFeatureFilter.Evaluate zugegriffen werden.
interface IFeatureFilterEvaluationContext {
featureName: string;
parameters?: unknown;
}
IFeatureFilterEvaluationContext hat eine Eigenschaft mit dem Namen parameters. Diese Parameter stellen eine unformatierte Konfiguration dar, die der Featurefilter verwenden kann, um zu entscheiden, wie das Feature aktiviert werden soll oder nicht. Um den Browserfeaturefilter als Beispiel erneut zu verwenden, könnte der Filter parameters verwenden, um eine Reihe zulässiger Browser zu extrahieren, die für das Feature angegeben würden - und überprüfen Sie dann, ob die Anforderung von einem dieser Browser gesendet wird.
Verwenden eines Anwendungskontexts für die Featureauswertung
Ein Featurefilter benötigt möglicherweise Laufzeitanwendungskontext, um ein Featureflag auszuwerten. Sie können den Kontext beim Aufrufen von isEnabled als Parameter übergeben.
featureManager.isEnabled("Beta", { userId : "Sam" })
Der Featurefilter kann den Kontext nutzen, der beim Aufrufen von isEnabled übergeben wird. Der Anwendungskontext wird als zweiter Parameter von IFeatureFilter.Evaluate übergeben.
Integrierte Funktionsfilter
Es gibt zwei Featurefilter, die im FeatureManagement Paket enthalten sind: TimeWindowFilter und TargetingFilter. Alle integrierten Featurefilter werden beim Erstellen FeatureManagerstandardmäßig hinzugefügt.
Jeder der integrierten Featurefilter verfügt über eigene Parameter. Hier ist die Liste der Featurefilter zusammen mit Beispielen.
Microsoft.TimeWindow
Dieser Filter bietet die Möglichkeit, ein Feature basierend auf einem Zeitfenster zu aktivieren. Wenn nur End angegeben ist, wird die Funktion bis zu diesem Zeitpunkt als eingeschaltet angesehen. Wenn nur Start angegeben ist, wird das Feature ab diesem Zeitpunkt als aktiv angesehen.
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
Das Zeitfenster kann so konfiguriert werden, dass es regelmäßig wieder auftritt. Dies kann für szenarien nützlich sein, in denen ein Feature möglicherweise während eines niedrigen oder hohen Datenverkehrszeitraums eines Tages oder bestimmter Wochentage aktiviert werden muss. Um das einzelne Zeitfenster auf wiederkehrende Zeitfenster zu erweitern, sollte die Serienregel im Recurrence Parameter angegeben werden.
Hinweis
Start und End müssen beide angegeben werden, um Recurrence zu aktivieren.
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Fri, 22 Mar 2024 20:00:00 GMT",
"End": "Sat, 23 Mar 2024 02:00:00 GMT",
"Recurrence": {
"Pattern": {
"Type": "Daily",
"Interval": 1
},
"Range": {
"Type": "NoEnd"
}
}
}
}
]
Die Recurrence Einstellungen bestehen aus zwei Teilen: Pattern (wie oft das Zeitfenster wiederholt wird) und Range (wie lange das Serienmuster wiederholt wird).
Serienmuster
Es gibt zwei mögliche Serienmustertypen: Daily und Weekly. Beispielsweise könnte ein Zeitfenster "jeden Tag", "alle drei Tage", "jeden Montag" oder "jeden anderen Freitag" wiederholen.
Je nach Typ sind bestimmte Felder des Pattern erforderlich, optional oder ignoriert.
DailyDas tägliche Serienmuster bewirkt, dass das Zeitfenster basierend auf einer Anzahl von Tagen zwischen jeder Ausführung wiederholt wird.
Eigenschaft Relevance Beschreibung Typ Erforderlich Muss auf Dailyfestgelegt sein.Intervall Wahlfrei Gibt die Anzahl der Tage zwischen jedem Vorkommen an. Der Standardwert ist 1. WeeklyDas wöchentliche Serienmuster bewirkt, dass das Zeitfenster am selben Tag oder an tagen der Woche basierend auf der Anzahl der Wochen zwischen den einzelnen Vorkommen wiederholt wird.
Eigenschaft Relevance Beschreibung Typ Erforderlich Muss auf Weeklyfestgelegt sein.DaysOfWeek Erforderlich Gibt an, an welchen Wochentagen das Ereignis eintritt. Intervall Wahlfrei Gibt die Anzahl der Wochen zwischen den einzelnen Ausführungen an. Der Standardwert ist 1. FirstDayOfWeek Wahlfrei Gibt an, welcher Tag als erster Tag der Woche gilt. Der Standardwert ist Sunday.Im folgenden Beispiel wird das Zeitfenster jeden zweiten Montag und Dienstag wiederholt.
"Pattern": { "Type": "Weekly", "Interval": 2, "DaysOfWeek": ["Monday", "Tuesday"] }
Hinweis
Start muss ein gültiges erstes Vorkommen sein, das zum Serienmuster passt. Darüber hinaus kann die Dauer des Zeitfensters nicht länger sein als die Anzahl der Vorkommen. Beispielsweise ist es ungültig, dass täglich ein 25-Stunden-Zeitfenster wieder auftritt.
Wiederholungsbereich
Es gibt drei mögliche Serienbereichstypen: NoEnd, EndDate und Numbered.
NoEndDer
NoEndBereich bewirkt, dass die Wiederholung endlos auftritt.Eigenschaft Relevance Beschreibung Typ Erforderlich Muss auf NoEndfestgelegt sein.EndDateDer
EndDateBereich bewirkt, dass das Zeitfenster an allen Tagen auftritt, die dem entsprechenden Muster bis zum Enddatum entsprechen.Eigenschaft Relevance Beschreibung Typ Erforderlich Muss auf EndDatefestgelegt sein.EndDate Erforderlich Gibt das Datum an, zu dem das Anwenden des Musters beendet werden soll. Solange die Startzeit des letzten Vorkommens vor dem Enddatum liegt, darf sich die Endzeit dieses Vorkommens darüber erstrecken. Im folgenden Beispiel wird das Zeitfenster jeden Tag wiederholt, bis das letzte Vorkommen am 1. April 2024 erfolgt.
"Start": "Fri, 22 Mar 2024 18:00:00 GMT", "End": "Fri, 22 Mar 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Daily", "Interval": 1 }, "Range": { "Type": "EndDate", "EndDate": "Mon, 1 Apr 2024 20:00:00 GMT" } }NumberedDer
NumberedBereich bewirkt, dass das Zeitfenster in einer festen Anzahl von Wiederholungen (basierend auf dem Muster) auftritt.Eigenschaft Relevance Beschreibung Typ Erforderlich Muss auf Numberedfestgelegt sein.AnzahlDerVorkommen Erforderlich Gibt die Anzahl der Vorkommen an. Im folgenden Beispiel wird das Zeitfenster montags und dienstags wiederholt, bis es drei Vorkommen gibt, die jeweils am 1. April (Mon), 2. April (Di) und 8.April(Mon) auftreten.
"Start": "Mon, 1 Apr 2024 18:00:00 GMT", "End": "Mon, 1 Apr 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Weekly", "Interval": 1, "DaysOfWeek": ["Monday", "Tuesday"] }, "Range": { "Type": "Numbered", "NumberOfOccurrences": 3 } }
Um eine Serienregel zu erstellen, müssen Sie sowohl Pattern als auch Range angeben. Jeder Mustertyp kann mit jedem Bereichstyp verwendet werden.
Erweitert: Der Zeitzonenoffset der Start-Eigenschaft wird auf die Serieneinstellungen angewendet.
Microsoft.Targeting
Dieser Filter bietet die Möglichkeit, ein Feature für eine Zielgruppe zu aktivieren. Eine ausführliche Erläuterung der Zielbestimmung wird im folgenden Abschnitt zur Zielbestimmung erläutert. Die Filterparameter enthalten ein Audience-Objekt, das Benutzer, Gruppen, ausgeschlossene Benutzer/Gruppen und einen Standardprozentsatz der Benutzerbasis beschreibt, die Zugriff auf das Feature haben sollen. Jedes Gruppenobjekt, das im Groups-Abschnitt aufgeführt ist, muss auch angeben, welcher Prozentsatz der Mitglieder der Gruppe Zugriff haben soll. Wenn ein Benutzer im Exclusion-Abschnitt angegeben wird, entweder direkt oder wenn sich der Benutzer in einer ausgeschlossenen Gruppe befindet, ist das Feature deaktiviert. Andernfalls gilt Folgendes: Wenn Benutzende direkt im Users-Abschnitt angegeben werden oder wenn die Benutzenden im Prozentsatz einer der Gruppenrollouts enthalten sind oder wenn die Benutzenden in den Prozentsatz des Standardrollouts fällt, wird das Feature für diese Benutzenden aktiviert.
"client_filters": [
{
"name": "Microsoft.Targeting",
"parameters": {
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
},
{
"Name": "Ring1",
"RolloutPercentage": 50
}
],
"DefaultRolloutPercentage": 20,
"Exclusion": {
"Users": [
"Ross"
],
"Groups": [
"Ring2"
]
}
}
}
}
]
Zielbestimmung
Die Zielbestimmung ist eine Featureverwaltungsstrategie, mit der Entwickler neue Features schrittweise für ihre Benutzerbasis bereitstellen können. Die Strategie basiert auf dem Konzept der Zielgruppenadressierung einer Gruppe von Benutzern, die als Zielgruppe bezeichnet werden. Eine Benutzergruppe besteht aus bestimmten Benutzern, Gruppen, ausgeschlossenen Benutzern/Gruppen und einem bestimmten Prozentsatz der gesamten Benutzerbasis. Die Gruppen, die in der Zielgruppe enthalten sind, können weiter in Prozentsätze ihrer Gesamtmitglieder unterteilt werden.
Die folgenden Schritte veranschaulichen ein Beispiel für ein progressives Rollout für ein neues Feature „Beta“:
- Individuelle Benutzende Jeff und Alicia erhalten Zugriff auf die Betaversion.
- Ein anderer Benutzer, Mark, fordert die Anmeldung an und wird aufgenommen.
- Zwanzig Prozent einer Gruppe, die als „Ring1“-Benutzer bezeichnet wird, sind in der Betaversion enthalten.
- Die Anzahl der in der Betaversion enthaltenen „Ring1“-Benutzende wird auf 100 Prozent erhöht.
- Fünf Prozent der Benutzerbasis werden in die Beta einbezogen.
- Der Rollout-Prozentsatz wird auf 100 Prozent erhöht, und das Feature wird vollständig eingeführt.
Diese Strategie für den Rollout eines Features ist über den enthaltenen Microsoft.Targeting-Featurefilter in die Bibliothek integriert.
Benutzeradressierung mit Zielkontext
Der Zielfilter basiert auf einem Zielkontext, um zu bewerten, ob ein Feature aktiviert werden soll. Dieser Zielkontext enthält Informationen, z. B. die aktuell ausgewertete benutzende Person und zu welchen Gruppen sie gehört. Der Zielkontext muss direkt übergeben werden, wenn isEnabled aufgerufen wird.
featureManager.isEnabled("Beta", { userId: "Aiden", groups: ["Ring1"] })
Zielausschluss
Beim Definieren einer Zielgruppe können Benutzer und Gruppen von der Zielgruppe ausgeschlossen werden. Ausschlüsse sind nützlich, wenn ein Feature für eine Gruppe von Benutzern eingeführt wird, aber einige Benutzer oder Gruppen aus dem Rollout ausgeschlossen werden müssen. Der Ausschluss wird durch Hinzufügen einer Liste von Benutzern und Gruppen zur Exclusion-Eigenschaft der Benutzergruppe definiert.
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
}
],
"DefaultRolloutPercentage": 0,
"Exclusion": {
"Users": [
"Mark"
]
}
}
Im obigen Beispiel ist das Feature für Benutzer mit dem Namen Jeff und Alicia aktiviert. Es ist auch für Benutzer in der Gruppe mit dem Namen Ring0 aktiviert. Wenn der Benutzer jedoch Mark benannt ist, ist das Feature deaktiviert, unabhängig davon, ob er sich in der Gruppe Ring0 befindet oder nicht. Ausschlüsse haben Vorrang vor dem Rest des Zielfilters.
Zielbestimmung in einer Webanwendung
Eine Beispielwebanwendung, die den Zielfeaturefilter verwendet, ist in diesem Beispielprojekt verfügbar.
In Webanwendungen, insbesondere solchen mit mehreren Komponenten oder Ebenen, kann das Übergeben des Zielkontexts (userId und groups) an jede Featureflagüberprüfung umständlich und monoton werden. Dieses Szenario wird als "Umgebungsadressierungskontext" bezeichnet, bei dem die Benutzeridentitätsinformationen bereits im Anwendungskontext (z. B. in Sitzungsdaten oder Authentifizierungskontext) verfügbar sind, aber für Featureverwaltungsbewertungen in der gesamten Anwendung zugänglich sein müssen.
ITargetingContextAccessor
Die Bibliothek stellt eine Lösung über das ITargetingContextAccessor Muster bereit.
interface ITargetingContext {
userId?: string;
groups?: string[];
}
interface ITargetingContextAccessor {
getTargetingContext: () => ITargetingContext | undefined;
}
Anstatt den Zielkontext explizit mit jedem isEnabled Oder getVariant Aufruf zu übergeben, können Sie eine Funktion bereitstellen, die weiß, wie die Zielinformationen des aktuellen Benutzers aus dem Kontext Ihrer Anwendung abgerufen werden:
import { FeatureManager, ConfigurationObjectFeatureFlagProvider } from "@microsoft/feature-management";
// Create a targeting context accessor that uses your application's auth system
const targetingContextAccessor = {
getTargetingContext: () => {
// In a web application, this might access request context or session data
// This is just an example - implement based on your application's architecture
return {
userId: getCurrentUserId(), // Your function to get current user
groups: getUserGroups() // Your function to get user groups
};
}
};
// Configure the feature manager with the accessor
const featureManager = new FeatureManager(featureProvider, {
targetingContextAccessor: targetingContextAccessor
});
// Now you can call isEnabled without explicitly providing targeting context
// The feature manager will use the accessor to get the current user context
const isBetaEnabled = await featureManager.isEnabled("Beta");
Dieses Muster eignet sich besonders bei serverseitigen Webanwendungen, bei denen der Benutzerkontext in einem Anforderungsbereich oder in Clientanwendungen verfügbar sein kann, bei denen die Benutzeridentität zentral verwaltet wird.
Verwenden von AsyncLocalStorage für anforderungskontext
Eine häufige Herausforderung bei der Implementierung des Zielkontextaccessormusters ist die Aufrechterhaltung des Anforderungskontexts in einer asynchronen Aufrufkette. In Node.js Webanwendungen sind Benutzeridentitätsinformationen in der Regel im Anforderungsobjekt verfügbar, können jedoch nicht mehr verwendet werden, wenn Sie asynchrone Vorgänge eingeben.
Node.js stellt AsyncLocalStorage vom async_hooks Modul zur Lösung dieses Problems bereit. Es erstellt einen Speicher, der über asynchrone Vorgänge innerhalb desselben logischen "Kontexts" hinweg beibehalten wird – perfekt für die Verwaltung von Anforderungsdaten während des gesamten Anforderungslebenszyklus.
Hier erfahren Sie, wie Sie einen Zielkontextaccessor mithilfe von AsyncLocalStorage in einer Expressanwendung implementieren:
import { AsyncLocalStorage } from "async_hooks";
import express from "express";
const requestAccessor = new AsyncLocalStorage();
const app = express();
// Middleware to store request context
app.use((req, res, next) => {
// Store the request in AsyncLocalStorage for this request chain
requestAccessor.run(req, () => {
next();
});
});
// Create targeting context accessor that retrieves user data from the current request
const targetingContextAccessor = {
getTargetingContext: () => {
// Get the current request from AsyncLocalStorage
const request = requestAccesor.getStore();
if (!request) {
return undefined; // Return undefined if there's no current request
}
// Extract user data from request (from session, auth token, etc.)
return {
userId: request.user?.id,
groups: request.user?.groups || []
};
}
};
Varianten
Wenn einer Anwendung neue Features hinzugefügt werden, kann es vorkommen, dass ein Feature über mehrere verschiedene vorgeschlagene Entwurfsoptionen verfügt. Eine gängige Lösung für die Entscheidung für ein Design ist eine Form von A/B-Tests, die beinhaltet, eine andere Version des Features für verschiedene Segmente der Benutzerbasis bereitzustellen und eine Version basierend auf der Benutzerinteraktion auszuwählen. In dieser Bibliothek wird diese Funktionalität aktiviert, indem verschiedene Konfigurationen eines Features mit Varianten dargestellt werden.
Varianten ermöglichen es einer Feature-Flag, mehr als nur eine einfache Ein/Aus-Option zu sein. Eine Variante stellt einen Wert einer Featurekennzeichnung dar, die eine Zeichenfolge, eine Zahl, ein boolescher Wert oder sogar ein Konfigurationsobjekt sein kann. Ein Featureflag, das Varianten deklariert, sollte definieren, unter welchen Umständen jede Variante verwendet werden soll, was im Abschnitt Zuweisen von Varianten ausführlicher behandelt wird.
Abrufen einer Variante mit Zielkontext
Für jedes Feature kann eine Variante mithilfe der FeatureManager-Methode von getVariant abgerufen werden. Die Zuweisung der Variante hängt von dem Benutzer ab, der momentan ausgewertet wird, und diese Informationen werden aus dem übergebenen Zielkontext abgerufen. Wenn Sie einen Zielkontextaccessor für FeatureManager registriert haben, wird der Zielkontext automatisch daraus abgerufen. Sie können ihn jedoch weiterhin überschreiben, indem Sie den Zielkontext beim Aufrufen von getVariant manuell übergeben.
const variant = await featureManager.getVariant("MyVariantFeatureFlag", { userId: "Sam" });
const variantName = variant.name;
const variantConfiguration = variant.configuration;
// Do something with the resulting variant and its configuration
Deklaration von Variantenfeatureflags
Im Vergleich zu normalen Featureflags weisen Variantenfeatureflags zwei zusätzliche Eigenschaften auf: variants und allocation. Die variants-Eigenschaft ist ein Array, das die für dieses Feature definierten Varianten enthält. Die allocation-Eigenschaft definiert, wie diese Varianten für das Feature zugewiesen werden sollen. Genau wie beim Deklarieren normaler Featureflags können Sie Varianten-Featureflags in einer JSON-Datei einrichten. Hier sehen Sie ein Beispiel für ein Variantenfeatureflag.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"default_when_enabled": "Small",
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
]
},
"variants": [
{
"name": "Big"
},
{
"name": "Small"
}
]
}
]
}
}
Definieren von Varianten
Jede Variante verfügt über zwei Eigenschaften: einen Namen und eine Konfiguration. Der Name wird verwendet, um auf eine bestimmte Variante zu verweisen, und die Konfiguration ist der Wert dieser Variante. Die Konfiguration kann mithilfe der Eigenschaft configuration_value festgelegt werden.
configuration_value ist eine Inlinekonfiguration, die ein Zeichenfolgen-, Zahlen-, boolesches oder Konfigurationsobjekt sein kann. Wenn configuration_value nicht angegeben wird, ist die Eigenschaft configuration der zurückgegebenen Variante undefined.
Für jedes Feature unter der variants-Eigenschaft wird eine Liste aller möglichen Varianten definiert.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"variants": [
{
"name": "Big",
"configuration_value": {
"Size": 500
}
},
{
"name": "Small",
"configuration_value": {
"Size": 300
}
}
]
}
]
}
}
Zuweisen von Varianten
Der Prozess der Zuordnung der Varianten eines Features wird durch die allocation-Eigenschaft des Features bestimmt.
"allocation": {
"default_when_disabled": "Small",
"default_when_enabled": "Small",
"user": [
{
"variant": "Big",
"users": [
"Marsha"
]
}
],
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
],
"percentile": [
{
"variant": "Big",
"from": 0,
"to": 10
}
],
"seed": "13973240"
},
"variants": [
{
"name": "Big",
"configuration_value": "500px"
},
{
"name": "Small",
"configuration_value": "300px"
}
]
Die allocation-Einstellung eines Features weist die folgenden Eigenschaften auf:
| Eigenschaft | Beschreibung |
|---|---|
default_when_disabled |
Gibt an, welche Variante verwendet werden soll, wenn eine Variante angefordert wird, während das Feature als deaktiviert gilt. |
default_when_enabled |
Gibt an, welche Variante verwendet werden soll, wenn eine Variante angefordert wird, während das Feature als aktiviert gilt und dem Benutzer keine andere Variante zugewiesen wurde. |
user |
Gibt eine Variante und eine Liste von Benutzern an, denen diese Variante zugewiesen werden soll. |
group |
Gibt eine Variante und eine Liste von Gruppen an. Die Variante wird zugewiesen, wenn sich der Benutzer in mindestens einer der Gruppen befindet. |
percentile |
Gibt eine Variante und einen Prozentbereich an, in den der berechnete Prozentsatz des Benutzers passt, damit diese Variante zugewiesen werden soll. |
seed |
Der Wert, auf dem prozentuale Berechnungen für percentile basieren. Die prozentuale Berechnung für einen bestimmten Benutzer ist für alle Features gleich, wenn derselbe seed-Wert verwendet wird. Wenn kein seed angegeben wird, wird basierend auf dem Merkmalsnamen ein Standard-Seed erstellt. |
Wenn das Feature nicht aktiviert ist, weist der Feature-Manager dem aktuellen Benutzer die als default_when_disabled markierte Variante zu, die in diesem Fall Small ist.
Wenn das Feature aktiviert ist, prüft der Feature-Manager die Zuweisungen von user, group und percentile in dieser Reihenfolge, um eine Variante zuzuweisen. Wenn der ausgewertete Benutzer Marsha heißt, zur Gruppe Ring1 gehört oder der Benutzer in das Perzentil zwischen 0 und 10 fällt, wird dem Benutzer die angegebene Variante zugewiesen. In diesem Fall würden alle zugewiesenen Benutzer die Variante Big zurückgeben. Wenn keine dieser Zuordnungen übereinstimmt, wird dem Benutzer die default_when_enabled-Variante zugewiesen, die Small ist.
Die Zuordnungslogik ähnelt dem Microsoft.Targeting-Featurefilter, aber es gibt einige Parameter, die in der Zielbestimmung vorhanden sind, die nicht in der Zuordnung enthalten sind, und umgekehrt. Die Ziel- und Zuordnungsergebnisse hängen nicht zusammen.
Überschreiben des aktivierten Zustands mit einer Variante
Sie können Varianten verwenden, um den aktivierten Status einer Featurekennzeichnung außer Kraft zu setzen. Die Überschreibung bietet Varianten die Möglichkeit, die Auswertung eines Featureflags zu erweitern. Wenn is_enabled bei einem Flag mit Varianten aufgerufen wird, überprüft der Featureverwalter, ob die dem aktuellen Benutzer zugewiesene Variante so konfiguriert ist, dass sie das Ergebnis überschreibt. Die Überschreibung erfolgt mithilfe der optionalen Varianteneigenschaft status_override. Diese Eigenschaft ist standardmäßig auf None festgelegt, was bedeutet, dass die Variante keine Auswirkungen darauf hat, ob die Kennzeichnung als aktiviert oder deaktiviert gilt. Wenn Sie status_override auf Enabled festlegen, kann die Variante bei Auswahl eine zu aktivierende Kennzeichnung außer Kraft setzen. Das Festlegen von status_override auf Disabled bietet die entgegengesetzte Funktionalität, wodurch die Kennzeichnung deaktiviert wird, wenn die Variante ausgewählt wird. Ein Feature mit einem enabled-Status von false kann nicht außer Kraft gesetzt werden.
Wenn Sie ein Featureflag mit binären Varianten verwenden, kann die status_override-Eigenschaft hilfreich sein. Sie können APIs wie is_enabled in Ihrer Anwendung weiterhin verwenden, während Sie von den neuen Features profitieren, die mit Varianten einhergehen, z. B. Perzentilzuweisung und Seed.
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"percentile": [
{
"variant": "On",
"from": 10,
"to": 20
}
],
"default_when_enabled": "Off",
"seed": "Enhanced-Feature-Group"
},
"variants": [
{
"name": "On"
},
{
"name": "Off",
"status_override": "Disabled"
}
]
}
Im obigen Beispiel ist das Feature immer aktiviert. Wenn sich der aktuelle Benutzer im berechneten Quantilbereich von 10 bis 20 befindet, wird die On-Variante zurückgegeben. Andernfalls wird die Off-Variante zurückgegeben und da status_override gleich Disabled ist, wird das Feature jetzt als deaktiviert betrachtet.
Telemetrie
Wenn eine Featurekennzeichnungsänderung bereitgestellt wird, ist es häufig wichtig, ihre Auswirkungen auf eine Anwendung zu analysieren. Hier sind beispielsweise einige Fragen, die auftauchen können:
- Sind meine Kennzeichnungen wie erwartet aktiviert/deaktiviert?
- Erhalten bestimmte Benutzer den Zugriff auf ein bestimmtes Feature wie erwartet?
- Welche Variante sieht ein bestimmter Benutzer?
Diese Fragen können durch die Ausgabe und Analyse von Auswertungsereignissen von Featureflags beantwortet werden.
Aktivieren der Telemetrie
Standardmäßig senden Feature-Flags keine Telemetriedaten. Um Telemetrie für ein bestimmtes Featureflag zu veröffentlichen, MUSS das Flag deklarieren, dass es für die Telemetrieausgabe aktiviert ist.
Bei Featureflags, die in JSON definiert sind, erfolgt die Aktivierung mithilfe der telemetry-Eigenschaft.
{
"feature_management": {
"feature_flags": [
{
"id": "MyFeatureFlag",
"enabled": true,
"telemetry": {
"enabled": true
}
}
]
}
}
Der obige Codeschnipsel definiert ein Featureflag namens MyFeatureFlag, das für Telemetrie aktiviert ist. Die telemetry-Eigenschaft des enabled-Objekts ist auf true festgelegt. Der Wert der enabled-Eigenschaft muss true sein, um Telemetrie für die Kennzeichnung zu veröffentlichen.
Der telemetry-Abschnitt einer Featurekennzeichnung weist die folgenden Eigenschaften auf:
| Eigenschaft | Beschreibung |
|---|---|
enabled |
Gibt an, ob Telemetrie für die Featurekennzeichnung veröffentlicht werden soll. |
metadata |
Eine Sammlung von Schlüsselwertpaaren, die als Wörterbuch modelliert werden, die verwendet werden können, um benutzerdefinierte Metadaten zur Featurekennzeichnung an Auswertungsereignisse anzufügen. |
Benutzerdefinierter Telemetriedatenherausgeber
Sie können eine onFeatureEvaluated-Rückruffunktion registrieren, wenn Sie FeatureManager erstellen. Dieser Rückruf wird aufgerufen, wenn ein Featureflag ausgewertet wird und Telemetrie für dieses Flag aktiviert ist. Die Rückruffunktion übernimmt das Funktionsauswertungsergebnis als Parameter.
Das folgende Beispiel zeigt, wie Sie eine benutzerdefinierte Rückruffunktion implementieren, um Telemetrie mit den Informationen zu senden, die aus dem Featureauswertungsergebnis extrahiert wurden, und wie Sie diese beim Feature-Manager registrieren.
const sendTelemetry = (evaluationResult) => {
const featureId = evaluationResult.feature.id;
const featureEnabled = evaluationResult.enabled;
const targetingId = evaluationResult.targetingId;
const variantName = evaluationResult.variant?.name;
const variantAssignmentReason = evaluationResult.variantAssignmentReason;
// custom code to send the telemetry
// ...
}
const featureManager = new FeatureManager(featureProvider, { onFeatureEvaluated : sendTelemtry});
Application Insights-Integration
Die JavaScript-Featureverwaltungsbibliothek bietet Erweiterungspakete, die in Application Insights-SDKs integriert werden.
Application Insights bietet verschiedene SDKs für Web- und Node.js-Szenarien. Wählen Sie die richtigen Erweiterungspakete für Ihre Anwendung aus.
Wenn Ihre Anwendung im Browser ausgeführt wird, installieren Sie das Paket "@microsoft/feature-management-applicationinsights-browser". Das folgende Beispiel zeigt, wie Sie einen integrierten Application Insights-Telemetrieherausgeber erstellen und beim Featuremanager registrieren können.
import { ApplicationInsights } from "@microsoft/applicationinsights-web"
import { FeatureManager, ConfigurationObjectFeatureFlagProvider } from "@microsoft/feature-management";
import { createTelemetryPublisher, trackEvent } from "@microsoft/feature-management-applicationinsights-browser";
const appInsights = new ApplicationInsights({ config: {
connectionString: "<APPINSIGHTS_CONNECTION_STRING>"
}});
appInsights.loadAppInsights();
const publishTelemetry = createTelemetryPublisher(appInsights);
const provider = new ConfigurationObjectFeatureFlagProvider(jsonObject);
const featureManager = new FeatureManager(provider, {onFeatureEvaluated: publishTelemetry});
// FeatureEvaluation event will be emitted when a feature flag is evaluated
featureManager.getVariant("TestFeature", {userId : TARGETING_ID}).then((variant) => { /* do something*/ });
// Emit a custom event with targeting id attached.
trackEvent(appInsights, TARGETING_ID, {name: "TestEvent"}, {"Tag": "Some Value"});
Der Telemetrieherausgeber sendet benutzerdefinierte FeatureEvaluation-Ereignisse an Application Insights, wenn ein mit Telemetrie aktiviertes Feature-Flag ausgewertet wird. Das benutzerdefinierte Ereignis folgt dem FeatureEvaluationEvent-Schema.
Zieltelemetrieprozessor
Wenn Sie implementiert ITargetingContextAccessorhaben, können Sie den integrierten Telemetrieprozessor für Application Insights verwenden, um zielbezogene ID-Informationen automatisch an alle Telemetriedaten anzufügen, indem Sie die createTargetingTelemetryProcessor Funktion aufrufen.
const appInsights = require("applicationinsights");
appInsights.setup(process.env.APPINSIGHTS_CONNECTION_STRING).start();
const { createTargetingTelemetryProcessor } = require("@microsoft/feature-management-applicationinsights-node");
appInsights.defaultClient.addTelemetryProcessor(
createTargetingTelemetryProcessor(targetingContextAccessor)
);
Dadurch wird sichergestellt, dass jedes an Application Insights gesendete Telemetrieelement die Informationen zur Zielgruppen-ID des Benutzers (userId und Gruppen) enthält, sodass Sie die Nutzung von Feature-Flags mit bestimmten Benutzern oder Gruppen in Ihrer Analyse korrelieren können.
Wenn Sie den Ziel-Telemetrieprozessor verwenden, können Sie die trackEvent Methode direkt aus dem Application Insights SDK aufrufen, anstatt die trackEvent vom Featureverwaltungspaket bereitgestellte Methode aufzurufen. Die Ziel-ID-Informationen werden automatisch an customDimensions der benutzerdefinierten Ereignistelemetriedaten angefügt.
// Instead of calling trackEvent and passing the app insights client
// trackEvent(appInsights.defaultClient, "<TARGETING_ID>", {name: "TestEvent", properties: {"Tag": "Some Value"}});
// directly call trackEvent method provided by App Insights SDK
appInsights.defaultClient.trackEvent({ name: "TestEvent" });
Nächste Schritte
Fahren Sie mit den folgenden Schnellstarts fort, um zu erfahren, wie Featureflags in Ihren Anwendungen verwendet werden.
Wenn Sie mehr über die Verwendung von Featurefiltern erfahren möchten, fahren Sie mit den folgenden Tutorials fort.