You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/azure-app-configuration/feature-management-javascript-reference.md
+118-2Lines changed: 118 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -449,6 +449,96 @@ When defining an audience, users and groups can be excluded from the audience. E
449
449
450
450
In the above example, the feature is enabled for users named `Jeff` and `Alicia`. It's also enabled for users in the group named `Ring0`. However, if the user is named `Mark`, the feature is disabled, regardless of if they are in the group `Ring0` or not. Exclusions take priority over the rest of the targeting filter.
451
451
452
+
### Targeting in a Web Application
453
+
454
+
An example web application that uses the targeting feature filter is available in this [example](https://github.com/microsoft/FeatureManagement-JavaScript/tree/preview/examples/express-app) project.
455
+
456
+
In web applications, especially those with multiple components or layers, passing targeting context (`userId` and `groups`) to every feature flag check can become cumbersome and repetitive. This scenario is referred to as "ambient targeting context," where the user identity information is already available in the application context (such as in session data or authentication context) but needs to be accessible to feature management evaluations throughout the application.
457
+
458
+
#### ITargetingContextAccessor
459
+
460
+
The library provides a solution through the `ITargetingContextAccessor` pattern.
Instead of explicitly passing the targeting context with each `isEnabled` or `getVariant` call, you can provide a function that knows how to retrieve the current user's targeting information from your application's context:
This pattern is particularly useful in server-side web applications where user context may be available in a request scope or in client applications where user identity is managed centrally.
501
+
502
+
#### Using AsyncLocalStorage for request context
503
+
504
+
One common challenge when implementing the targeting context accessor pattern is maintaining request context throughout an asynchronous call chain. In Node.js web applications, user identity information is typically available in the request object, but becomes inaccessible once you enter asynchronous operations.
505
+
506
+
Node.js provides [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage) from the `async_hooks` module to solve this problem. It creates a store that persists across asynchronous operations within the same logical "context" - perfect for maintaining request data throughout the entire request lifecycle.
507
+
508
+
Here's how to implement a targeting context accessor using AsyncLocalStorage in an express application:
509
+
510
+
```typescript
511
+
import { AsyncLocalStorage } from"async_hooks";
512
+
importexpressfrom"express";
513
+
514
+
const requestAccessor =newAsyncLocalStorage();
515
+
516
+
const app =express();
517
+
// Middleware to store request context
518
+
app.use((req, res, next) => {
519
+
// Store the request in AsyncLocalStorage for this request chain
520
+
requestAccessor.run(req, () => {
521
+
next();
522
+
});
523
+
});
524
+
525
+
// Create targeting context accessor that retrieves user data from the current request
526
+
const targetingContextAccessor = {
527
+
getTargetingContext: () => {
528
+
// Get the current request from AsyncLocalStorage
529
+
const request =requestContext.getStore();
530
+
if (!request) {
531
+
returnundefined; // Return undefined if there's no current request
532
+
}
533
+
// Extract user data from request (from session, auth token, etc.)
534
+
return {
535
+
userId: request.user?.id,
536
+
groups: request.user?.groups|| []
537
+
};
538
+
}
539
+
};
540
+
```
541
+
452
542
## Variants
453
543
454
544
When new features are added to an application, there may come a time when a feature has multiple different proposed design options. A common solution for deciding on a design is some form of A/B testing, which involves providing a different version of the feature to different segments of the user base and choosing a version based on user interaction. In this library, this functionality is enabled by representing different configurations of a feature with variants.
@@ -457,7 +547,7 @@ Variants enable a feature flag to become more than a simple on/off flag. A varia
457
547
458
548
### Getting a variant with targeting context
459
549
460
-
For each feature, a variant can be retrieved using the `FeatureManager`'s `getVariant` method. The variant assignment is dependent on the user currently being evaluated, and that information is obtained from the targeting context you passed in.
550
+
For each feature, a variant can be retrieved using the `FeatureManager`'s `getVariant` method. The variant assignment is dependent on the user currently being evaluated, and that information is obtained from the targeting context you passed in. If you have registered a targeting context accessor to the `FeatureManager`, the targeting context will be automatically retrieved from it. But you can still override it by manually passing targeting context when calling `getVariant`.
@@ -542,8 +632,8 @@ The process of allocating a feature's variants is determined by the `allocation`
542
632
543
633
```json
544
634
"allocation": {
545
-
"default_when_enabled": "Small",
546
635
"default_when_disabled": "Small",
636
+
"default_when_enabled": "Small",
547
637
"user": [
548
638
{
549
639
"variant": "Big",
@@ -751,6 +841,32 @@ trackEvent(appInsights.defaultClient, "<TARGETING_ID>", {name: "TestEvent", pro
751
841
752
842
The telemetry publisher sends `FeatureEvaluation` custom events to the Application Insights when a feature flag enabled with telemetry is evaluated. The custom event follows the [FeatureEvaluationEvent](https://github.com/microsoft/FeatureManagement/tree/main/Schema/FeatureEvaluationEvent) schema.
753
843
844
+
### Targeting telemetry processor
845
+
846
+
If you have implemented [`ITargetingContextAccessor`](#itargetingcontextaccessor), you can use the built-in Application Insights telemetry processor to automatically attach targeting ID information to all telemetry by calling the `createTargetingTelemetryProcessor` function.
This ensures that every telemetry item sent to Application Insights includes the user's targeting ID information (userId and groups), allowing you to correlate feature flag usage with specific users or groups in your analytics.
859
+
860
+
If you are using the targeting telemetry processor, instead of calling the `trackEvent` method provided by the feature management package, you can directly call the `trackEvent` method from the Application Insights SDK. The targeting ID information will be automatically attached to the custom event telemetry's `customDimensions`.
861
+
862
+
```typescript
863
+
// Instead of calling trackEvent and passing the app insights client
0 commit comments