Skip to content

Commit f02ea6e

Browse files
update
1 parent 37e6c20 commit f02ea6e

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

examples/express-app/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Examples for Microsoft Feature Management for JavaScript
2+
3+
These examples show how to use the Microsoft Feature Management in an express application.
4+
5+
## Prerequisites
6+
7+
The examples are compatible with [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule).
8+
9+
## Setup & Run
10+
11+
1. Install the dependencies using `npm`:
12+
13+
```bash
14+
npm install
15+
```
16+
17+
1. Run the examples:
18+
19+
```bash
20+
node server.mjs
21+
```
22+
23+
1. Visit `http://localhost:3000/Beta` and use `userId` and `groups` query to specify the targeting context (e.g. /Beta?userId=Jeff or /Beta?groups=Admin).
24+
25+
- If you are not targeted, you will get the message "Page not found".
26+
27+
- If you are targeted, you will get the message "Welcome to the Beta page!".
28+
29+
## Targeting
30+
31+
The targeting mechanism uses the `exampleTargetingContextAccessor` to extract the targeting context from the request. This function retrieves the userId and groups from the query parameters of the request.
32+
33+
```javascript
34+
const exampleTargetingContextAccessor = () => {
35+
const req = requestAccessor.getStore();
36+
const { userId, groups } = req.query;
37+
return { userId: userId, groups: groups ? groups.split(",") : [] };
38+
};
39+
```
40+
41+
The `FeatureManager` is configured with this targeting context accessor:
42+
43+
```javascript
44+
const featureManager = new FeatureManager(
45+
featureProvider,
46+
{
47+
targetingContextAccessor: exampleTargetingContextAccessor
48+
}
49+
);
50+
```
51+
52+
This allows you to get ambient targeting context while doing feature flag evaluation.
53+
54+
### Request Accessor
55+
56+
The `requestAccessor` is an instance of `AsyncLocalStorage` from the `async_hooks` module. It is used to store the request object in asynchronous local storage, allowing it to be accessed throughout the lifetime of the request. This is particularly useful for accessing request-specific data in asynchronous operations. For more information, please go to https://nodejs.org/api/async_context.html
57+
58+
```javascript
59+
import { AsyncLocalStorage } from "async_hooks";
60+
const requestAccessor = new AsyncLocalStorage();
61+
```
62+
63+
Middleware is used to store the request object in the AsyncLocalStorage:
64+
65+
```javascript
66+
server.use((req, res, next) => {
67+
requestAccessor.run(req, next);
68+
});
69+
```

examples/express-app/server.mjs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ const featureProvider = new ConfigurationObjectFeatureFlagProvider(config);
1111

1212
// https://nodejs.org/api/async_context.html
1313
import { AsyncLocalStorage } from "async_hooks";
14-
const asyncLocalStorage = new AsyncLocalStorage();
14+
const requestAccessor = new AsyncLocalStorage();
1515
const exampleTargetingContextAccessor = () => {
16-
const req = asyncLocalStorage.getStore();
16+
const req = requestAccessor.getStore();
1717
const { userId, groups } = req.query;
1818
return { userId: userId, groups: groups ? groups.split(",") : [] };
1919
};
@@ -31,11 +31,11 @@ const PORT = 3000;
3131

3232
// Use a middleware to store the request object in async local storage.
3333
// The async local storage allows the targeting context accessor to access the current request throughout its lifetime.
34-
// Middleware 1
34+
// Middleware 1 (request object is stored in async local storage here and it will be available across the following chained async operations)
3535
// Middleware 2
36-
// Request Handler (feature flag evaluation)
36+
// Request Handler (feature flag evaluation happens here)
3737
server.use((req, res, next) => {
38-
asyncLocalStorage.run(req, next);
38+
requestAccessor.run(req, next);
3939
});
4040

4141
server.get("/", (req, res) => {

0 commit comments

Comments
 (0)