LaunchDarkly Developer Documentation

Get started in under 30 minutes.
LaunchDarkly provides feature flags as a service for Java · Python · Ruby · Go · Node.js · PHP · .NET. Control feature launches -- who sees what and when -- without multiple code deploys. Easy dashboard for phased rollouts, targeting and segmenting.
Need more help? write us at support@launchdarkly.com

Get Started    Guides

Reading flags from a file

For automated tests or prototyping, you may wish to run application code that uses feature flags without actually connecting to LaunchDarkly. The normal behavior of the SDKs in offline mode is to return the default value for each flag evaluation ("default" in this case is not an actual property of the flag, but just the value that you specified as a fallback in your program code when you evaluated the flag).

However, in many of the server-side SDKs, you can also use files to set up the desired feature flag state. This feature is currently available in Go (version 4.4.0 and up), Java (4.5.0 and up), .NET (5.5.0 and up), Ruby (5.4.0 and up), Python (6.6.0 and up), and Node.js (5.7.0 and up). It is not intended for production use.

Creating a flag data file

Flag data files can be either JSON or YAML. They contain up to three properties:

  • flags: Feature flag definitions. These can contain all the same kinds of rules and targets that you can define in a LaunchDarkly feature flag, allowing the flag to produce different values for different users.
  • flagValues: Simplified feature flags that specify only a value (the same for all users).
  • segments: User segment definitions (if you have any feature flags that use segments).

The format of the data in flags and segments is defined by the LaunchDarkly application and is subject to change. Rather than trying to construct these objects yourself, it is simpler to request existing flags directly from the LaunchDarkly server in JSON format, and use this output as the starting point for your file. This can be obtained from the URL https://app.launchdarkly.com/sdk/latest-all, passing your SDK key in the Authorization header. For instance, in Linux, you could use this command:

curl -H "Authorization: MY_SDK_KEY" https://app.launchdarkly.com/sdk/latest-all >flagdata.json

The output will look something like this (but with many more properties):

{
  "flags": {
    "flag-key-1": {
      "key": "flag-key-1",
        "on": true,
        "variations": [ "a", "b" ]
      }
  },
  "segments": {
    "segment-key-1": {
      "key": "segment-key-1",
      "includes": [ "user-key-1" ]
    }
  }
}

Data in this format allows the SDK to exactly duplicate all the kinds of flag behavior supported by LaunchDarkly. However, in many cases you will not need this complexity, but will just want to set specific flag keys to specific values. For that, you can use a much simpler format:

{
  "flagValues": {
    "my-string-flag-key": "value-1",
    "my-boolean-flag-key": true,
    "my-integer-flag-key": 3
  }
}

Or, in YAML:

flagValues:
  my-string-flag-key: "value-1"
  my-boolean-flag-key: true
  my-integer-flag-key: 3

It is also possible to specify both flags and flagValues, if you want some flags to have simple values and others to have complex behavior. However, it is an error to use the same flag key or segment key more than once, either in a single file or across multiple files.

Configuring the client to use a file

In all of the SDKs that have this feature, you can specify either a single file or multiple files, and you can specify whether the SDK should reload the file data if it detects that you have modified a file (so, for instance, you could verify that your application behaves correctly when a flag is changed).

The examples below show how to configure the client to use two data files called file1.json and file2.json (which are assumed to be in the current working directory—you can specify any relative or absolute file path), and to enable automatic reloading.

Note that if you do not want your code to connect to LaunchDarkly at all, you will normally want to prevent the SDK from trying to send analytics events, so the option for disabling events is also included in these examples. Also, since there will be no LaunchDarkly connection, you do not have to use a valid SDK key; the SDK key parameter is still required but can be any string.

import (
    ld "gopkg.in/launchdarkly/go-client.v4"
    "gopkg.in/launchdarkly/go-client.v4/ldfiledata"
    "gopkg.in/launchdarkly/go-client.v4/ldfilewatch"
)

fileSource, err := ldfiledata.NewFileDataSourceFactory(
    ldfiledata.FilePaths("file1.json", "file2.json"),
    ldfiledata.UseReloader(ldfilewatch.WatchFiles))

config := ld.DefaultConfig
config.UpdateProcessorFactory = fileSource
config.SendEvents = false

client := ld.MakeCustomClient("sdk key", config, 5*time.Second)
import com.launchdarkly.client.*;
import com.launchdarkly.client.files.*;

FileDataSourceFactory fileSource = FileComponents.fileDataSource()
    .filePaths("file1.json", "file2.json")
    .autoUpdate(true);

LDConfig config = new LDConfig.Builder()
    .updateProcessorFactory(fileSource)
    .sendEvents(false)
    .build();

LDClient client = new LDClient("sdk key", config);
using LaunchDarkly.Client;
using LaunchDarkly.Client.Files;

var fileSource = FileComponents.FileDataSource()
    .WithFilePaths("file1.json", "file2.json")
    .WithAutoUpdate(true);

var config = Configuration.Default("sdk key")
    .WithUpdateProcessorFactory(fileSource)
    .WithEventProcessorFactory(Components.NullEventProcessor)
    .Build();

var client = new LDClient(config);

// Note that in the .NET SDK, if you want to use YAML files instead of JSON
// you must provide a YAML parser; see FileDataSourceFactory.WithParser.
require 'ldclient-rb'

factory = LaunchDarkly::FileDataSource.factory(
  paths: [ "file1.json", "file2.json" ],
  auto_update: true
)

config = LaunchDarkly::Config.new(
  update_processor_factory: factory,
  send_events: false
)

client = LaunchDarkly::Client.new("sdk key", config)

# Note that in the Ruby SDK, automatic reloading uses a somewhat inefficient
# file-polling mechanism unless you install the "listen" gem.
import ldclient
from ldclient.config import Config
from ldclient.file_data_source import FileDataSource

factory = FileDataSource.factory(paths=["file1.json", "file2.json"],
    auto_update=True)

config = Config(update_processor_class=factory, send_events=False)

ldclient.set_config(config)
ldclient.set_sdk_key("sdk key")
client = ldclient.get()

# Note that in the Python SDK, if you want to use YAML files instead of JSON
# you must install the "pyyaml" package. Also, automatic reloading uses a
# somewhat inefficient file-polling mechanism unless you install the "watchdog"
# package.
const LaunchDarkly = require('ldclient-node');

const dataSource = LaunchDarkly.FileDataSource({
  paths: [ "file1.json", "file2.json" ]
});

const config  = {
  updateProcessor: dataSource
};

const client = LaunchDarkly.init(sdkKey, config);

If any of the specified files is missing or invalid, the SDK will not use any of the file data and will log an error message.