Java SDK
Server-side feature flags for Java 11+ with built-in circuit breaker, zero external dependencies, caching, and SSE streaming support.
Circuit Breaker
Auto-recovery
Zero Dependencies
Uses java.net.http
Caching
Persistent cache
SSE Support
Real-time updates
Installation
<dependency>
<groupId>io.rollgate</groupId>
<artifactId>rollgate-sdk</artifactId>
<version>1.2.1</version>
</dependency>implementation 'io.rollgate:rollgate-sdk:1.2.1'Quick Start
import io.rollgate.RollgateClient;
import io.rollgate.RollgateConfig;
import java.time.Duration;
// Initialize once at startup
RollgateClient client = new RollgateClient(
RollgateConfig.builder()
.apiKey(System.getenv("ROLLGATE_API_KEY"))
.baseUrl("https://api.rollgate.io")
.refreshInterval(Duration.ofSeconds(30))
.build()
);
// Initialize and start polling
client.init();
// Check flags
boolean enabled = client.isEnabled("my-feature", false);
// Identify user
client.identify(UserContext.builder()
.id("user-123")
.email("[email protected]")
.attribute("plan", "pro")
.build());
// Cleanup on shutdown
client.close();Configuration
Configuration uses the builder pattern via RollgateConfig.builder().
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | String | required | Server API key (rg_server_...) |
| baseUrl | String | 'https://api.rollgate.io' | API base URL |
| refreshInterval | Duration | Duration.ofSeconds(30) | Polling interval, Duration.ZERO to disable |
| enableStreaming | boolean | false | Use SSE for real-time updates (opt-in) |
| timeout | Duration | Duration.ofSeconds(5) | HTTP request timeout |
RollgateConfig config = RollgateConfig.builder()
.apiKey(System.getenv("ROLLGATE_API_KEY"))
.baseUrl("https://api.rollgate.io")
.refreshInterval(Duration.ofSeconds(30))
.enableStreaming(false)
.timeout(Duration.ofSeconds(5))
.build();
RollgateClient client = new RollgateClient(config);Methods
init()
Initialize the client and fetch flags from the server. Must be called before evaluating any flags.
client.init();close()
Shut down the client, stop polling/streaming, and release resources.
client.close();isEnabled(key, defaultValue)
Check if a boolean flag is enabled. Returns the flag value or the default.
boolean showFeature = client.isEnabled("new-feature", false);
if (showFeature) {
// New feature code
}getValue(key, defaultValue)
Get a flag value of any type. Returns an Object that can be cast to the expected type.
Object value = client.getValue("feature-config", null);getString(key, defaultValue)
Type-safe helper for string flags.
String buttonColor = client.getString("cta-color", "blue");
String variant = client.getString("checkout-variant", "control");getNumber(key, defaultValue)
Type-safe helper for number flags.
double pageSize = client.getNumber("results-per-page", 20);
double timeout = client.getNumber("api-timeout-ms", 5000);getJSON<T>(key, defaultValue, clazz)
Type-safe helper for JSON flags. Deserializes the flag value into the specified class.
public class FeatureConfig {
public boolean enabled;
public int maxItems;
public List<String> allowedRoles;
}
FeatureConfig config = client.getJSON("feature-config",
new FeatureConfig(), FeatureConfig.class);
if (config.enabled && config.allowedRoles.contains(user.getRole())) {
// Feature logic
}getAllFlags()
Get all flags as a Map<String, Object>.
Map<String, Object> flags = client.getAllFlags();
// {"feature-a": true, "feature-b": false}identify(userContext)
Set user context for targeting rules. Re-fetches flags with the new context.
client.identify(UserContext.builder()
.id("user-123")
.email("[email protected]")
.attribute("plan", "enterprise") // For "plan in pro,enterprise" rules
.attribute("country", "US") // For "country equals US" rules
.attribute("company", "Acme Inc") // For "company contains Acme" rules
.attribute("app_version", "2.1.0") // For "app_version semver_gt 2.0.0" rules
.build());refresh()
Force refresh flags from the server.
client.refresh();Circuit Breaker
The SDK includes a circuit breaker that protects your app when Rollgate is unavailable. When open, it uses cached flag values.
// Get current state
String state = client.getCircuitState();
// "closed" | "open" | "half-open"
// Force reset (use with caution)
client.resetCircuit();Spring Boot Integration
Integrate Rollgate as a Spring Bean for dependency injection across your application.
import io.rollgate.RollgateClient;
import io.rollgate.RollgateConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PreDestroy;
import java.time.Duration;
@Configuration
public class RollgateConfiguration {
@Value("${rollgate.api-key}")
private String apiKey;
@Value("${rollgate.base-url:https://api.rollgate.io}")
private String baseUrl;
private RollgateClient client;
@Bean
public RollgateClient rollgateClient() {
client = new RollgateClient(
RollgateConfig.builder()
.apiKey(apiKey)
.baseUrl(baseUrl)
.refreshInterval(Duration.ofSeconds(30))
.build()
);
client.init();
return client;
}
@PreDestroy
public void cleanup() {
if (client != null) {
client.close();
}
}
}import io.rollgate.RollgateClient;
import org.springframework.stereotype.Service;
@Service
public class FeatureService {
private final RollgateClient rollgate;
public FeatureService(RollgateClient rollgate) {
this.rollgate = rollgate;
}
public boolean isFeatureEnabled(String featureKey) {
return rollgate.isEnabled(featureKey, false);
}
}rollgate:
api-key: ${ROLLGATE_API_KEY}
base-url: https://api.rollgate.ioError Handling & Graceful Degradation
The SDK is designed to never throw exceptions during flag evaluation. If Rollgate is unavailable, flags return their default values. Use these patterns for production-grade reliability:
// Default values ensure your app works even without Rollgate
boolean showNewFeature = client.isEnabled("new-feature", false);
// Returns false if: flag doesn't exist, API down, circuit open
// Monitor degraded state
String circuitState = client.getCircuitState();
boolean isHealthy = "closed".equals(circuitState);Initialization Error Handling
try {
client.init();
Map<String, Object> flags = client.getAllFlags();
System.out.println("Rollgate initialized with " + flags.size() + " flags");
} catch (Exception e) {
// Log but don't crash - SDK will use defaults
System.err.println("Rollgate init failed: " + e.getMessage());
System.err.println("Continuing with default flag values");
}
// Application starts regardless of Rollgate statusFeature-Critical Flags
For flags that control critical features, add explicit fallback logic:
public boolean shouldEnablePayments() {
// Critical feature: payments
boolean flagValue = client.isEnabled("payments-enabled", true); // Default: enabled
String circuitState = client.getCircuitState();
if ("open".equals(circuitState)) {
// Circuit is open, we're using cached values
// For payments, always enable as fail-safe
System.err.println("Circuit open, enabling payments as fail-safe");
return true;
}
return flagValue;
}