NodeJS SDK
The @featureboard/node-sdk
is a FeatureBoard SDK for NodeJS.
Prerequisites
Before using @featureboard/js-sdk
you will need to have a valid environmentApiKey
. To locate the Environment API Key, simply go to the “Project Settings” section and copy the key for your environment.
Installation
npm add --save @featureboard/node-sdk
# Or
yarn add @featureboard/node-sdk
# Or
pnpm add @featureboard/node-sdk
Setup
To integrate feature toggles in your Node.js project you need to create and configure the FeatureBoard service. The server client is created for a specific environment and the environment api key you can find by navigating to the “Project Settings” section.
import { createServerClient } from '@featureboard/node-sdk'
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
updateStrategy: 'polling',
externalStateStore: undefined,
api: undefined,
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
Input Parameters
environmentApiKey
- Specifies the environment api key for the environment.updateStrategy
- Configure preferred update strategy. The default strategy is polling at 30-second interval.externalStateStore
- Provides the option to configure external state store in cases where FeatureBoard is unavailable.api
- Provides the option to connect to a self-hosted instance of FeatureBoard.
Return Properties
Returns a ServerClient
object.
request()
- Get aFeatureBoardClient
based on an audience set.initialised
- Returns true once the FeatureBoard SDK has a valid set of feature values.waitForInitialised()
- Waits for the server client to be initialised. If initialisation fails an error is thrown.updateFeatures()
- Manually trigger the feature state store to update.close()
- Close the subscription to the FeatureBoard service.
Configuration Options
Choose Update Strategy
Our SDKs are designed to work with different update strategies. You can choose update strategy by configuring the updateStrategy
input parameter. Featureboard NodeJS SDK supports following update strategies:
- polling
- manual updating
- on request
Default update strategy is polling at 30-second interval.
Polling
To use polling update strategy you can configure updateStrategy
to 'polling'
and the server client will poll the FeatureBoard service at the default 30-second interval. To change the interval, you need to set intervalMs
in PollingOption
.
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
// Set update strategy to polling at default 30-second interval
updateStrategy: 'polling',
})
// or
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
// Set update strategy to polling at 5-second interval
updateStrategy: { kind: 'polling', options: { intervalMs: 5000 } },
})
Manual
If you prefer the application to have more direct control over features updates, you can configure 'updateStrategy'
to 'manual'
. To initiate the update process you utilise the updateFeature
function.
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
updateStrategy: 'manual',
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
// Triggers an update of the feature state store
await serverClient.updateFeatures()
On Request
This update strategy is useful for serverless applications where the VM gets paused between invocations, it will guarantee that the feature values are always up to date for the current invocation.
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
// Set update strategy to on request with default max age cache of 30 seconds
updateStrategy: 'on-request',
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
// NOTE: request function must be awaited when using the on-request strategy
const requestClient = await serverClient.request(['admin', 'plan-large'])
By default, the on-request strategy has a max age cache of 30 seconds. If you wish to reduce cache time, you can achieve that by providing an OnRequestOptions
configuration object. This configuration ensures that the SDK will only check if the feature values have changed after the max age has passed since the last update.
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
// Set update strategy to on request with max age cache of 1 second
updateStrategy: { kind: 'on-request', options: { maxAgeMs: 1000 } },
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
// NOTE: request function must be awaited when using the on-request strategy
const requestClient = await serverClient.request(['admin', 'plan-large'])
Note: The request function must be awaited when using the on-request update strategy. If not awaited an error will be thrown.
External State Store
You can provide the server client with the last know set of feature values by implementing the ExternalStateStore
interface. If FeatureBoard is unavailable during initialisation, the SDK will retrieve features from the external state store by calling all
. To keep the external state store accurate, the SDK will call update
with a copy of the internal state store each time a feature is changed.
import { ExternalStateStore } from '@featureboard/node-sdk'
import { FeatureConfiguration } from '@featureboard/contracts'
export class YourExternalStateStore implements ExternalStateStore {
private store: Record<string, FeatureConfiguration | undefined> = {}
async all(): Promise<Record<string, FeatureConfiguration | undefined>> {
// Return a stable copy of the feature values
return { ...this.store }
}
async update(store: Record<string, FeatureConfiguration | undefined>): PromiseLike<any> {
// Update the external state store with the provided feature values
this.store = { ...store }
return Promise.resolve()
}
}
import { createServerClient } from '@featureboard/node-sdk'
const myStateStore = new YourExternalStateStore()
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
externalStateStore: myStateStore,
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
Note: The SDK will ignore any errors thrown in update
.
Self Hosted Instance
By configuring the api
input parameter you can connect to a shelf hosted instance of FeatureBoard.
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
api: {
http: 'https://my-featureboard-endpoint'
ws: 'wss://my-websocket-featureboard-endpoint'
},
})
Wait For Initialised
Before you begin using the FeatureBoard server client, it is important to ensure that the server client has been initialised with feature values. You achieve this by awaiting the waitForInitialised
function.
In the unlikely event of encountering a connectivity issue with FeatureBoard, the server client will make multiple retry attempts. If the retries fails, FeatureBoard will try to initiate by using the external state store if it has been defined. If all fail, waitForInitialised
will throw an error. To handle this error, you can wrap the waitForInitialised
function in a try-catch block. This way, you can handle any potential issues that might arise during the initialisation process.
try {
const serverClient = createServerClient({
environmentApiKey: 'my-environment-api-key',
})
// Wait for the server client to initialise
await serverClient.waitForInitialised()
} catch (err: any) {
// An error occurred during initialisation
throw err
}
Usage
To retrieve feature values, you will need to untilise the FeatureBoardClient
, which is based on an audience set. This would normally happen at the beginning of an HTTP request within your Node.js application.
This setup is designed to ensure that FeatureBoard does not impact response times of your application. It allows the SDK to calculate the feature values for that user based on their audiences on the fly in memory.
// Get the FeatureBoard client for the current request
const client = serverClient.request(['audience-key-1', 'audience-key-2'])
Get Feature Value
The getFeatureValue
function returns the feature value for a given feature. The default value is used as a fallback in cases where the feature is unavailable in the current environment.
// First get the FeatureBoard client for the current request
const client = serverClient.request(['audience-key-1', 'audience-key-2'])
// Then use the client in your application to get the current feature value.
// NOTE: You must specify a default value, this is used when the feature is unavailable in this environment
const featureValue = client.getFeatureValue('my-feature-key', defaultValue)
Universal JavaScript Applications
For universal JavaScript applications where you want to use the SDK on the server and client, the SDK returned from the request
message is the same shape as the client from @featureboard/js-sdk
, making FeatureBoard SDKs easy to use with frameworks like Next.js.
Note: When subscribeToFeatureValue
is used in FeatureBoard Node SDK, it will only call back once. It will immediately call back with the current value but will not subscribe to the feature in the state store.
TypeScript
When using TypeScript add an ambient type definition using Declaration Merging typing your features, for example
declare module '@featureboard/js-sdk' {
interface Features {
'test-feature-1': boolean
'test-feature-2': string
'test-feature-2b': string
'test-feature-3': number
}
}
If you do not want to specify all your features the features you can just add:
declare module '@featureboard/js-sdk' {
interface Features extends Record<string, string | number | boolean> {}
}