Skip to main content

Node js client

Install

npm install izanami-node

Import

const Izanami = require("izanami-node");

Usage

The node client expose conveniant methods to call Izanami.

Configure the client:

const izanamiConfig = Object.assign({}, Izanami.defaultConfig, {
host: "http://localhost:9000",
clientId: process.env.CLIENT_ID || "xxxx",
clientSecret: process.env.CLIENT_SECRET || "xxxx",
});

// Get a configs client
const configClient = Izanami.configClient(izanamiConfig);
// Get a feature client
const featureClient = Izanami.featureClient(izanamiConfig);
// Get a experiments client
const experimentsClient = Izanami.experimentsClient(izanamiConfig);

Configs

Get a config

configClient.config("my.config.id").then((config) => {
console.log("The config is ", config);
tree.should.be.deep.equal({
value: "test",
});
});

Get the configs tree

configClient.configs("my.config.*").then((tree) => {
tree.should.be.deep.equal({
my: {
config: {
id: {
value: "test",
},
id2: {
another: {
value: "a value",
},
},
},
},
});
});

Features

Check a feature

featureClient.checkFeature("my.feature.id").then((active) => {
console.log("The feature is ", active);
});

Or with a context:

featureClient
.checkFeature("my.feature.id", { client: "ragnard.lodbrock@gmail.com" })
.then((active) => {
console.log("The feature is ", active);
});

Get the features tree

featureClient.features("my.feature.*").then((tree) => {
tree.should.be.deep.equal({
my: {
feature: {
id: {
active: true,
},
id2: {
active: false,
},
},
},
});
});

Or with a context:

featureClient
.features("my.feature.*", { client: "ragnard.lodbrock@gmail.com" })
.then((tree) => {
tree.should.be.deep.equal({
my: {
feature: {
id: {
active: true,
},
id2: {
active: false,
},
},
},
});
});

Experiments

Get an experiment

experimentsClient.experiment("my.experiment.id").then((experiment) => {
//Empty json if the experiment doesn't exists
console.log("The experiment is ", experiment);
});

Get experiments as tree

experimentsClient
.experiments("my.experiment.*", "ragnard.lodbrock@gmail.com")
.then((tree) => {
//Empty json if the experiment doesn't exists
console.log("The experiment is ", experiment);
tree.should.be.deep.equal({
my: {
experiment: {
id: {
variant: "A",
},
id2: {
variant: "B",
},
},
},
});
});

Get a variant

experimentsClient
.variantFor("my.experiment.id", "ragnard.lodbrock@gmail.com")
.then((variant) => {
//Empty json if the variant doesn't exists
console.log("The variant is ", variant);
});

Mark variant displayed

experimentsClient
.displayed("my.experiment.id", "ragnard.lodbrock@gmail.com")
.then((__) => {
console.log("The variant is marked displayed");
});

Mark variant won

experimentsClient
.won("my.experiment.id", "ragnard.lodbrock@gmail.com")
.then((__) => {
console.log("The variant is marked won");
});

Express proxy

You use express as a proxy to expose Izanami to the client side. You can customize the api endpoints with the sessionPath, experimentsDisplayedPath and experimentsWonPath config options.

Context (optional) and clientId (require) are extracted from the request, and forward respectively at the feature and experiments api; you can customize extraction by using your own methods with featureContextFromRequest and experimentsClientIdFromRequest.

const app = express();

Izanami.expressProxy({
sessionPath: "/api/izanami", // default '/api/me'
experimentsDisplayedPath, // default: '/api/experiments/displayed'
experimentsWonPath, // default: '/api/experiments/won'
featureClient, // Optional
featureContextFromRequest, //default: (req) => ({id: req.user_email})
experimentsClient, // Optional
experimentsClientIdFromRequest, //default: (req) => (req.user_email)
configClient, // Optional
app, // Express app
path: "my.namespace.*", // The pattern to filter experiments, configs and features
});