Skip to main content

Node

Eppo's open source Node SDK can be used for both feature flagging and experiment assignment:

Getting Started

Install the SDK

You can install the SDK with Yarn or NPM:

yarn add @eppo/node-server-sdk

Define an assignment logger

Eppo encourages centralizing application logging as much as possible. Accordingly, instead of implementing a new logging framework, Eppo's SDK integrates with your existing logging system via a logging callback function defined at SDK initialization.

The code below illustrates an example implementation of a logging callback to the console and other event platforms. You could also use your own logging system, the only requirement is that the SDK receives a logAssignment function. Here we define an implementation of the Eppo IAssignmentLogger interface containing a single function named logAssignment:

// Import Eppo's assignment logger interface and client initializer
import { IAssignmentLogger, init } from "@eppo/node-server-sdk";

// Define logAssignment so that it logs events
const assignmentLogger: IAssignmentLogger = {
logAssignment(assignment) {
console.log(assignment)
},
};

Avoiding duplicated assignment logs

Eppo's SDK uses an internal cache to ensure that duplicate assignment events are not logged to the data warehouse. While Eppo's analytic engine will automatically deduplicate assignment records, this internal cache prevents firing unnecessary events and can help minimize costs associated with event logging.

Initialize the SDK

Initialize the SDK with an SDK key, which can be generated in the Eppo interface. Initialization should happen when your application starts up to generate a singleton client instance, once per application lifecycle:

import { init } from "@eppo/node-server-sdk";

await init({
apiKey: "<SDK_KEY>",
assignmentLogger,
});

After initialization, the SDK begins polling Eppo’s API at regular intervals to retrieve the most recent experiment configurations such as variation values and traffic allocation. The SDK stores these configurations in memory so that assignments thereafter are effectively instant. For more information, see the architecture overview page.

Assign variations

Assign users to flags or experiments using get<Type>Assignment, depending on the type of the flag. For example, for a String-valued flag, use getStringAssignment:

import * as EppoSdk from "@eppo/node-server-sdk";

const eppoClient = EppoSdk.getInstance();
const variation = eppoClient.getStringAssignment(
"<FLAG-KEY>",
"<SUBJECT-KEY>",
<SUBJECT-ATTRIBUTES>, // Metadata used for targeting
"<DEFAULT-VALUE>",
);

The getStringAssignment function takes three required and one optional input to assign a variation:

  • flagKey - This key is available on the detail page for both flags and experiments. Can also be an experiment key.
  • subjectKey - The entity ID that is being experimented on, typically represented by a uuid.
  • subjectAttributes - A map of metadata about the subject used for targeting. If you create rules based on attributes on a flag/experiment, those attributes should be passed in on every assignment call. If no attributes are needed, pass in an empty object.
  • defaultValue - The value that will be returned if no allocation matches the subject, if the flag is not enabled, if getStringAssignment is invoked before the SDK has finished initializing, or if the SDK was not able to retrieve the flag configuration. Its type must match the get<Type>Assignment call.

Example

See an end-to-end example below of setting up the Eppo Node client and logging events to the console.

// Import Eppo's assignment logger interface and client initializer
import { IAssignmentLogger, init } from "@eppo/node-server-sdk";

// Define logAssignment so that it logs events
const assignmentLogger: IAssignmentLogger = {
logAssignment(assignment) {
console.log(assignment)
},
};

// Initialize the client
await init({
apiKey: "<SDK_KEY>",
assignmentLogger,
});

// Then every call to getStringAssignment will also log the event
const user = {
userid: '1234567890',
attributes: { country: 'united states', subscription_status: 'gold' }
}

const eppoClient = EppoSdk.getInstance();
const variation = eppoClient.getStringAssignment(
"new-user-onboarding",
user.userid,
user.attributes
"control",
);
// Output
{
allocation: 'allocation-2468',
experiment: 'new-user-onboarding-allocation-2468',
featureFlag: 'new-user-onboarding',
variation: 'treatment',
timestamp: '2024-03-21T18:58:23.176Z',
subject: '1234567890',
holdout: 'q1-holdout',
holdoutVariation: null,
subjectAttributes: { country: 'united states', subscription_status: 'gold' }
}
note

It may take up to 10 seconds for changes to Eppo experiments to be reflected by the SDK assignments.

Typed assignments

The following typed functions are available:

getBoolAssignment(...)
getNumericAssignment(...)
getIntegerAssignment(...)
getStringAssignment(...)
getJSONAssignment(...)

To read more about different flag types, see the page on Flag Variations.

Initialization options

How the SDK fetches experiment configurations is configurable via additional optional initialization options:

OptionDescriptionDefault
requestTimeoutMs (number)Timeout in milliseconds for HTTPS requests for the experiment configurations.5000
numInitialRequestRetries (number)Number of additional times the initial configurations request will be attempted if it fails. This is the request typically synchronously waited (via await) for completion. A small wait will be done between requests.1
pollAfterFailedInitialization (boolean)Poll for new configurations even if the initial configurations request failed.false
throwOnFailedInitialization (boolean)Throw an error (reject the promise) if unable to fetch initial configurations during initialization.true
numPollRequestRetries (number)If polling for updated configurations after initialization, the number of additional times a request will be attempted before giving up. Subsequent attempts are done using an exponential backoff.7

Assignment Logger schema

The SDK will invoke the logAssignment function with an assignment object that contains the following fields:

FieldDescriptionExample
experiment (string)An Eppo experiment key"recommendation-algo-allocation-17"
subject (string)An identifier of the subject or user assigned to the experiment variationUUID
variation (string)The experiment variation the subject was assigned to"control"
timestamp (string)The time when the subject was assigned to the variation2021-06-22T17:35:12.000Z
subjectAttributes (map)A free-form map of metadata about the subject. These attributes are only logged if passed to the SDK assignment function{ "country": "US" }
featureFlag (string)An Eppo feature flag key"recommendation-algo"
allocation (string)An Eppo allocation key"allocation-17"
holdout (string)An Eppo holdout group key"q1-holdout"
holdoutVariation (string)An Eppo holdout variation if experiment is eligible for analysis key"status_quo", "all_shipped_variations", or null
note

More details about logging and examples (with Segment, Rudderstack, mParticle, Snowplow, Amplitude) can be found in the event logging page.