TogglerOne Client is a Java library for evaluating feature flags using a hybrid approach. It attempts to evaluate flags directly via a server POST request and falls back to a locally cached, token-based evaluation using a compiled Abstract Syntax Tree (AST) when direct evaluation fails. The client automatically refreshes tokens for tracked flags at a configurable interval, ensuring that fallback data is always available even if the server goes down.
Note: This project requires Java 17 or later.
-
Direct Server Evaluation:
Sends a POST request to one or more configured endpoints for immediate flag evaluation. -
Cached AST Fallback:
When direct evaluation fails, the client uses a locally cached AST generated from previously downloaded tokens. -
Automatic Token Refresh:
Tokens are refreshed automatically in the background at a configurable frequency (default 30 seconds, with a minimum of 10 seconds).
Flags to be refreshed can be pre-registered or added dynamically during evaluation. -
Thread-Safe & Lightweight:
Uses Java's built-inHttpClient
and concurrent collections to safely operate in multi-threaded environments.
- Java 17 or later
- Jackson for JSON processing
- The specdrivendesign/lql libraries for AST parsing and bytecode handling
Add the following dependency to your build.gradle
file:
dependencies {
implementation 'com.github.specdrivendesign:togglerone:1.0.0'
}
Include the following dependency in your pom.xml
:
<dependency>
<groupId>com.github.specdrivendesign</groupId>
<artifactId>togglerone</artifactId>
<version>0.0.8</version>
</dependency>
You can initialize the client with a list of endpoints, your RSA public key for token verification, and optionally a list of flags to pre-register along with a custom refresh frequency. If no flags are provided, flags will be added automatically when evaluated.
import com.github.specdrivendesign.togglerone.Client;
import com.github.specdrivendesign.togglerone.Client.FlagIdentifier;
import java.security.interfaces.RSAPublicKey;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class FeatureFlagExample {
public static void main(String[] args) throws Exception {
// Define your endpoints.
List<String> endpoints = Arrays.asList("https://api.example.com");
// Load your RSA public key for token verification.
RSAPublicKey publicKey = ...; // Provide your RSA public key here
// Optionally, pre-register flags to be refreshed.
List<FlagIdentifier> flags = Arrays.asList(
new FlagIdentifier("org1", "flagA"),
new FlagIdentifier("org1", "flagB")
);
// Create the client with a custom refresh frequency (30 seconds by default).
Client client = new Client(endpoints, publicKey, flags, Duration.ofSeconds(30));
// Evaluate a flag; if the flag is not already tracked, it will be added automatically.
Object result = client.evaluateFlag("org1", "flagA", Map.of("user", "alice"));
System.out.println("Feature flag result: " + result);
// When finished, shutdown the client to stop background refresh.
client.shutdown();
}
}
-
Client(List<String> endpoints, RSAPublicKey publicKey)
Creates a client without any initial flags. Flags will be added dynamically when evaluated. -
Client(List<String> endpoints, RSAPublicKey publicKey, List<FlagIdentifier> flags, Duration refreshFrequency)
Creates a client with pre-registered flags and a custom token refresh frequency (minimum 10 seconds, default is 30 seconds). -
evaluateFlag(String org, String flagName, Map<String, Object> inputContext)
Evaluates a feature flag. The method first attempts a direct server evaluation; if that fails, it falls back to a locally cached AST. -
shutdown()
Shuts down the background token refresh scheduler.