Feature Management - Launch Darkly

Feature Management - Launch Darkly

“LaunchDarkly provides simple, scalable feature flag & toggle management (feature management) for the modern enterprise.”

You can create a trial account at launchdarkly.com and their docs are at docs.launchdarkly.com are really good.

All the code snippets below are available at https://github.com/carlpaton/LaunchDarklyDemo

Launch Darkly packages

The API’s for the Launch Darkly client are avalible in these SDKs

Launch Darkly Projects & Environments

Each Launch Darkly project can have multiple environments, the default project is called Default Project but you can add more.

Each environment has its own SDK key, when creating the client this is a required parameter. The default environments are Test and Production. Its sensible for your code to have no knowledge of the environments and simply rely on the correct SDK key to be injected.

An example SDK key could look like sdk-00000000-0000-0000-0000-000000000000 (this is not the same as a REST clients Authorization access token, example api-00000000-0000-0000-0000-000000000000)

The first time you create your environment, the GUI will prompt you to connect as SDK - mine was at https://app.launchdarkly.com/default/production/get-started/connect-an-sdk

Example client:

1
2
var launchDarklyClient = new LdClient(_sdkKey);
services.AddSingleton<ILdClient>(launchDarklyClient);

Segments

Segments can be applied to a flag, see this newer post for more details.

Local development

When developing locally the LdClient can be configured to return pre-defined settings. This would also be useful when running integration tests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (_environment.IsDevelopment() 
{
var dataSource = FileData
.DataSource()
.FilePaths("foo/bar/LocalLdClientFeatures.json");

var config = Configuration.Builder(_sdkKey)
.DataSource(dataSource)
.Events(Components.NoEvents)
.Build();

var launchDarklyClient = new LdClient(config);
services.AddSingleton<ILdClient>(launchDarklyClient);
}

SDK

BoolVariation

The examples below assume _sdkKey is injected and the features sweet-feature-name-1 and sweet-feature-name-2 has been configured in Launch Darkly.

User.WithKey

This works with both LaunchDarkly.Client or LaunchDarkly.ServerSdk.

This example will return true only when the userId of cc04e5b8-b483-47fe-8ce6-0098487e91a8 is configured in Launch Darkly under the flag sweet-feature-name-1.

1
2
3
4
5
6
7
8
9
// V7.0.3
var defaultValue = false;
var userId = "e3dbd64b-f51d-4aff-a4e5-f334960b9045";
var featureName = "sweet-feature-name-3";

var context = Context.New(userId);
var allowed = ldClient.BoolVariation(featureName, context, defaultValue);

Console.WriteLine("CheckByUserKey: userId={0} returned allowed={1}", userId, allowed);
1
2
3
4
5
6
7
8
9
10
// V6.2.0
var defaultValue = false;
var userId = "cc04e5b8-b483-47fe-8ce6-0098487e91a8";
var featureName = "sweet-feature-name-1";

var ldClient = new LdClient(_sdkKey);
var ldUser = User.WithKey(userId);
var allowed = ldClient.BoolVariation(featureName, ldUser, defaultValue);

Console.WriteLine("CheckByUserKey: userId={0} returned allowed={1}", userId, allowed);

User.WithKey

User.Builder

This only works with LaunchDarkly.ServerSdk.

This example will return true when either of the following is configured in Launch Darkly under the flag sweet-feature-name-2. These are custom fields in Launch Darkly.

  • cityId of ea2b6efc-020d-4469-a993-1bd5baf78adc
    OR
  • regionId of nz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// V7.0.3
var defaultValue = false;
var userId = Guid.NewGuid().ToString().ToLowerInvariant(); // this is not validated in LD
var cityId = "ea2b6efc-020d-4469-a993-1bd5baf78adc";
var regionId = "nz";
var featureName = "sweet-feature-name-2";

var context = Context
.Builder(userId)
.Set("CityId", cityId)
.Set("RegionId", regionId);

var allowed = ldClient.BoolVariation(featureName, context.Build(), defaultValue);

Console.WriteLine("CheckByCustom: cityId={0} with regionId={1} returned allowed={2}",
cityId,
regionId,
allowed);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// V6.2.0
var defaultValue = false;
var userId = Guid.NewGuid().ToString().ToLowerInvariant(); // this is not validated in LD
var cityId = "ea2b6efc-020d-4469-a993-1bd5baf78adc";
var regionId = "nz";
var featureName = "sweet-feature-name-2";

var ldClient = new LdClient(_sdkKey);
var ldUser = User
.Builder(userId)
.Custom("CityId", cityId)
.Custom("RegionId", regionId)
.Build();

var allowed = ldClient.BoolVariation(featureName, ldUser, defaultValue);

Console.WriteLine("CheckByCustom: cityId={0} with regionId={1} returned allowed={2}",
cityId,
regionId,
allowed);

User.Builder