$ npm install --save nestjs-unleash
Import the module with UnleashModule.forRoot(...)
or UnleashModule.forRootAsync(...)
.
Use UnleashModule.forRoot()
. Available options are described in the UnleashModuleOptions interface.
@Module({
imports: [
UnleashModule.forRoot({
url: "https://example.com/unleash",
appName: "my-app-name",
instanceId: "my-unique-instance",
}),
],
})
export class MyModule {}
If you want to use your Unleash options dynamically, use UnleashModule.forRootAsync()
. Use useFactory
and inject
to import your dependencies. Example using the ConfigService
:
@Module({
imports: [
UnleashModule.forRootAsync({
useFactory: (config: ConfigService) => ({
url: config.get("UNLEASH_URL"),
appName: config.get("UNLEASH_APP_NAME"),
instanceId: config.get("UNLEASH_INSTANCE_ID"),
refreshInterval: config.get("UNLEASH_REFRESH_INTERVAL"),
metricsInterval: config.get("UNLEASH_METRICS_INTERVAL"),
}),
inject: [ConfigService],
}),
],
})
export class MyModule {}
In your controller use the UnleashService
or the @IfEnabled(...)
route decorator:
import { UnleashService } from "nestjs-unleash";
@Controller()
@UseGuards(UserGuard)
export class AppController {
constructor(private readonly unleash: UnleashService) {}
@Get("/")
index(): string {
// the UnleashService can be used in all controllerrs and provideers
return this.unleash.isEnabled("test")
? "feature is active"
: "feature is not active";
}
// Throws a NotFoundException if the feature is not enabled
@IfEnabled("test")
@Get("/foo")
getFoo(): string {
return "my foo";
}
}
The UnleashContext
grants access to request related information like user ID or IP address.
In addition, the context can be dynamically enriched with further information and subsequently used in a separate strategy:
export interface MyCustomData {
foo: string;
bar: number;
}
@Injectable()
class SomeProvider {
constructor(private readonly unleash: UnleashService<MyCustomData>) {}
someMethod() {
return this.unleash.isEnabled("someToggleName", undefined, {
foo: "bar",
bar: 123,
})
? "feature is active"
: "feature is not active";
}
}
// Custom strategy with custom data:
@Injectable()
export class MyCustomStrategy implements UnleashStrategy {
name = "MyCustomStrategy";
isEnabled(
_parameters: unknown,
context: UnleashContext<MyCustomData>
): boolean {
return context.customData?.foo === "bar";
}
}
NestJS-Unleash can be configured with the following options:
interface UnleashModuleOptions {
/**
* If "true", registers `UnleashModule` as a global module.
* See: https://docs.nestjs.com/modules#global-modules
*
* @default true
*/
global?: boolean;
/**
* URL of your Unleash server
*
* @example http://unleash.herokuapp.com/api/client
*/
url: string;
/**
* Name of the application seen by unleash-server
*/
appName: string;
/**
* Instance id for this application (typically hostname, podId or similar)
*/
instanceId: string;
/**
* Additional options for the HTTP request to the Unleash server, e.g. custom
* HTTP headers
*/
http?: AxiosRequestConfig;
/**
* At which interval, in milliseconds, will this client update its feature
* state
*/
refreshInterval?: number;
/**
* At which interval, in milliseconds, will this client send metrics
*/
metricsInterval?: number;
/**
* Array of custom strategies. These classes mus implement the `UnleashStrategy` interface.
*/
strategies?: Type<UnleashStrategy>[];
/**
* `nestjs-unleash` sends an initial registration request to the unleash server at startup. This behavior can be disabled by this option.
*/
disableRegistration?: boolean;
/**
* Some strategies depend on the user ID of the currently logged in user. The
* user ID is expected by default in `request.user.id`. To customize this
* behavior, a custom user ID factory can be provided.
*/
userIdFactory?: (request: Request<{ id: string }>) => string;
}
This module supports the official standard activation strategies. They do not need to be activated separately and work out of the box.
In order to create a custom strategy you have to create a class wich inplements the UnleashStrategy
interface:
import { UnleashContext } from "nestjs-unleash";
export interface UnleashStrategy {
/**
* Must match the name you used to create the strategy in your Unleash
* server UI
*/
name: string;
/**
* Determines whether the feature toggle is active
*
* @param parameters Custom paramemters as configured in Unleash server UI
* @param context applicaton/request context, i.e. UserID
*/
isEnabled(parameters: unknown, context: UnleashContext): boolean;
}
Example custom strategy:
import { Injectable } from "@nestjs/common";
import { UnleashContext, UnleashStrategy } from "nestjs-unleash";
@Injectable()
export class MyCustomStrategy implements UnleashStrategy {
name = "MyCustomStrategy";
isEnabled(parameters: any, context: UnleashContext): boolean {
return Math.random() < 0.5;
}
}
Now you can use it your module setup as follows:
import { MyCustomStrategy } from "./my-custom-strategy";
@Module({
imports: [
UnleashModule.forRoot({
// ...
strategies: [MyCustomStrategy],
}),
],
})
export class ApplicationModule {}
nestjs-unleash is distributed under the MIT license. See LICENSE for details.