Skip to content

Commit b336b1b

Browse files
committed
Documentation for dd-trace with feature flagging support
1 parent be89ca2 commit b336b1b

File tree

2 files changed

+194
-7
lines changed

2 files changed

+194
-7
lines changed

content/en/feature_flags/setup/ios.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ FlagsClient.create(name: "checkout")
126126
let flagsClient = FlagsClient.shared(named: "checkout")
127127
{{< /code-block >}}
128128

129-
<div class="alert alert-info">If a client with the given name already exists, the existing instance is reused.</div>
129+
<div class="alert alert-info">If a client with the given name already exists, the existing instance is reused.</div>
130130

131131
## Set the evaluation context
132132

@@ -232,10 +232,10 @@ let config = flagsClient.getObjectValue(
232232

233233
When you need more than just the flag value, use the `get<Type>Details` APIs. These methods return both the evaluated value and metadata explaining the evaluation:
234234

235-
* `getBooleanDetails(key:defaultValue:) -> FlagDetails<Bool>`
236-
* `getStringDetails(key:defaultValue:) -> FlagDetails<String>`
237-
* `getIntegerDetails(key:defaultValue:) -> FlagDetails<Int>`
238-
* `getDoubleDetails(key:defaultValue:) -> FlagDetails<Double>`
235+
* `getBooleanDetails(key:defaultValue:) -> FlagDetails<Bool>`
236+
* `getStringDetails(key:defaultValue:) -> FlagDetails<String>`
237+
* `getIntegerDetails(key:defaultValue:) -> FlagDetails<Int>`
238+
* `getDoubleDetails(key:defaultValue:) -> FlagDetails<Double>`
239239
* `getObjectDetails(key:defaultValue:) -> FlagDetails<AnyValue>`
240240

241241
For example:
@@ -274,8 +274,8 @@ Flags.enable(with: config)
274274

275275
The exact behavior of Graceful Mode depends on your build configuration:
276276

277-
* **Release builds**: The SDK always enforces Graceful Mode: any misuse is only logged internally if `Datadog.verbosityLevel` is configured.
278-
* **Debug builds** with `gracefulModeEnabled = true` (default): The SDK always logs warnings to the console.
277+
* **Release builds**: The SDK always enforces Graceful Mode: any misuse is only logged internally if `Datadog.verbosityLevel` is configured.
278+
* **Debug builds** with `gracefulModeEnabled = true` (default): The SDK always logs warnings to the console.
279279
* **Debug builds** with `gracefulModeEnabled = false`: The SDK raises `fatalError` for incorrect API usage, enforcing a fail-fast approach that helps detect configuration mistakes early.
280280

281281
You can adjust `gracefulModeEnabled` depending on your development or QA phase.
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
---
2+
title: Node.js Feature Flags Support
3+
description: Set up Datadog Feature Flags for Node.js applications.
4+
further_reading:
5+
- link: "/feature_flags/setup/"
6+
tag: "Documentation"
7+
text: "Feature Flags Setup"
8+
- link: "/apm/"
9+
tag: "Documentation"
10+
text: "APM Setup"
11+
---
12+
13+
## Installing and initializing
14+
15+
Feature Flagging is provided by APM. To integrate APM into your application with feature flagging support, install `dd-trace` and enable remote configuration with the `flaggingProvider` option as shown below. See documentation on `dd-trace` integration for detailed APM installation instructions.
16+
17+
```shell
18+
npm install dd-trace @openfeature/server-sdk
19+
```
20+
21+
```javascript
22+
import { OpenFeature } from '@openfeature/server-sdk'
23+
import tracer from 'dd-trace';
24+
25+
tracer.init({
26+
experimental: {
27+
flaggingProvider: {
28+
enabled: true,
29+
}
30+
}
31+
});
32+
33+
OpenFeature.setProvider(tracer.openfeature);
34+
```
35+
36+
### Accepting default variant until initialization is complete
37+
38+
When you call `setProvider` without waiting, the client returns default values until remote configuration loads in the background. This approach keeps your application responsive during startup but may serve defaults for early requests.
39+
40+
```javascript
41+
OpenFeature.setProvider(tracer.openfeature);
42+
const client = OpenFeature.getClient();
43+
44+
app.get('/my-endpoint', (req, res) => {
45+
const value = client.getBooleanValue('my-flag', false);
46+
if (value) {
47+
res.send('feature enabled!');
48+
} else {
49+
res.send('feature disabled!');
50+
}
51+
});
52+
```
53+
54+
### Waiting for initialization before evaluating a flag
55+
56+
Use `setProviderAndWait` to ensure the provider fully initializes before evaluating flags. This guarantees that flag evaluations use actual configuration data rather than defaults, at the cost of delaying requests during initialization.
57+
58+
```javascript
59+
const initializationPromise = OpenFeature.setProviderAndWait(tracer.openfeature);
60+
const client = OpenFeature.getClient();
61+
62+
app.get('/my-endpoint', async (req, res) => {
63+
await initializationPromise;
64+
65+
OpenFeature.setContext({
66+
userID: req.session?.userID,
67+
companyID: req.session?.companyID
68+
});
69+
70+
const value = client.getBooleanValue('my-flag', false);
71+
if (value) {
72+
res.send('feature enabled!');
73+
} else {
74+
res.send('feature disabled!');
75+
}
76+
});
77+
```
78+
79+
## Set the evaluation context
80+
81+
Define who or what the flag evaluation applies to using an `EvaluationContext`. The evaluation context can include user or session information used to determine which flag variations should be returned. Call `OpenFeature.setContext` method before evaluating flags to ensure proper targeting.
82+
83+
## Evaluating flags
84+
85+
After creating the `OpenFeature` client as described in the previous section, you can start reading flag values throughout your app. Flag evaluation uses locally cached data, so no network requests occur when evaluating flags.
86+
87+
Each flag is identified by a _key_ (a unique string) and can be evaluated with a _typed getter_ that returns a value of the expected type. If the flag doesn't exist or cannot be evaluated, the SDK returns the provided default value.
88+
89+
### Boolean flags
90+
91+
Use `getBooleanValue()` for flags that represent on/off or true/false conditions. Optionally set the context for specific targeting rules.
92+
93+
```javascript
94+
OpenFeature.setContext({
95+
userID: req.session?.userID,
96+
companyID: req.session?.companyID
97+
});
98+
99+
const isNewCheckoutEnabled = client.getBooleanValue(
100+
'new-checkout-flow', // flag key
101+
false, // default value
102+
);
103+
104+
if (isNewCheckoutEnabled) {
105+
showNewCheckoutFlow();
106+
} else {
107+
showLegacyCheckout();
108+
}
109+
```
110+
111+
### String flags
112+
113+
Use `getStringValue()` for flags that select between multiple variants or configuration strings. For example:
114+
115+
```javascript
116+
OpenFeature.setContext({
117+
userID: req.session?.userID,
118+
companyID: req.session?.companyID
119+
});
120+
121+
const theme = client.getStringValue(
122+
'ui-theme', // flag key
123+
'light', // default value
124+
);
125+
126+
switch (theme) {
127+
case 'light':
128+
setLightTheme()
129+
case 'dark':
130+
setDarkTheme()
131+
case 'blue':
132+
setBlueTheme()
133+
default:
134+
setLightTheme()
135+
}
136+
```
137+
138+
### Number flags
139+
140+
For number flags, use `getNumberValue()`. This is appropriate when a feature depends on a numeric parameter such as a limit, percentage, or multiplier:
141+
142+
```javascript
143+
const maxItems = client.getNumberValue(
144+
'max-cart-items', // flag key
145+
20, // default value
146+
);
147+
148+
const priceMultiplier = client.getNumberValue(
149+
'pricing-multiplier', // flag key
150+
1.3, // default value
151+
);
152+
```
153+
154+
### Object flags
155+
156+
For structured JSON data, use `getObjectValue()`. This method returns an `object`, which can represent primitives, arrays, or dictionaries. Object flags are useful for remote configuration scenarios where multiple properties need to be provided together.
157+
158+
```javascript
159+
const defaultConfig = {
160+
color: '#00A3FF',
161+
fontSize: 14,
162+
};
163+
const config = client.getObjectValue('ui-config', defaultConfig);
164+
165+
```
166+
167+
### Flag evaluation details
168+
169+
When you need more than just the flag value, use the `get<Type>Details` functions. These methods return both the evaluated value and metadata explaining the evaluation:
170+
171+
* `getBooleanDetails() -> EvaluationDetails<boolean>`
172+
* `getStringDetails() -> EvaluationDetails<string>`
173+
* `getNumberDetails() -> EvaluationDetails<number>`
174+
* `getObjectDetails() -> EvaluationDetails<JsonValue>`
175+
176+
For example:
177+
178+
```javascript
179+
const details = client.getStringDetails('paywall-layout', 'control');
180+
181+
console.log(details.value); // Evaluated value (for example: "A", "B", or "control")
182+
console.log(details.variant); // Variant name, if applicable
183+
console.log(details.reason); // Description of why this value was chosen (for example: "TARGETING_MATCH")
184+
console.log(details.errorCode); // The error that occurred during evaluation, if any
185+
console.log(details.errorMessage); // A more detailed message of the error that occurred, if any
186+
console.log(details.flagMetadata); // Additional information about the evaluation
187+
```

0 commit comments

Comments
 (0)