# 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):

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

Maven:

```xml
<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`](/sdks/web).

## Sync at startup

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

```java
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:

```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:

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

```kotlin
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:

```java
Runtime.getRuntime().addShutdownHook(new Thread(flags::close));
```

```kotlin
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.
