SDKs

flagbearer for Java and Kotlin

The Java SDK for Flagbearer, usable from Kotlin and other JVM languages. Requires Java 11 or later.

Install

Gradle (Kotlin DSL):

dependencies {
    implementation("dev.flagbearer:flagbearer:0.1.0")
}

Maven:

<dependency>
  <groupId>dev.flagbearer</groupId>
  <artifactId>flagbearer</artifactId>
  <version>0.1.0</version>
</dependency>

Keys

Use a server key, which starts with fbs_. Server keys are secret: read them from the environment, such as FLAGBEARER_SERVER_KEY, and never put them in browser code or in the repository. Browsers use client keys, which start with fbc_, through @flagbearer/web.

Sync at startup

Create one client per process, when the app starts, and wait for it to sync before accepting requests:

import dev.flagbearer.Flagbearer;
import dev.flagbearer.FlagbearerClient;
import dev.flagbearer.FlagbearerException;
import java.time.Duration;

FlagbearerClient flags = Flagbearer.init(System.getenv("FLAGBEARER_SERVER_KEY"));
try {
    flags.sync(Duration.ofSeconds(10));
} catch (FlagbearerException error) {
    // Keep starting: checks use their defaults, and the SDK retries in the background.
    logger.warn("Initial Flagbearer sync failed", error);
}

In Kotlin:

val flags = Flagbearer.init(System.getenv("FLAGBEARER_SERVER_KEY"))
try {
    flags.sync(Duration.ofSeconds(10))
} catch (error: FlagbearerException) {
    // Keep starting: checks use their defaults, and the SDK retries in the background.
    logger.warn("Initial Flagbearer sync failed", error)
}

Check per request

Pass each request's user explicitly, and a default:

@GetMapping("/search")
public Results search(@AuthenticationPrincipal Account account) {
    User user = User.of(account.getId(), account.getEmail());
    boolean advanced = flags.isEnabled("advanced-search", user, false);
    // …
}
val advanced = flags.isEnabled("advanced-search", User.of(account.id, account.email), false)

The email is optional. Include it to turn flags on for testers by email. The default is used until the client has synced, and when the flag doesn't exist. A null key or email means unset.

Shut down

Keep the client for the life of the process, not per request. Close it on shutdown. In Spring, a @Bean closes on shutdown by itself:

Runtime.getRuntime().addShutdownHook(new Thread(flags::close));
Flagbearer.init(System.getenv("FLAGBEARER_SERVER_KEY")).use { flags ->
    flags.sync()
    runApp(flags)
}

Serverless functions should call flags.flush() at the end of each invocation.