Skip to content

Reference

SDKs and integrations

Use a FluxGate SDK for Java, TypeScript or Rust, an OpenFeature SDK with the OFREP provider for any other language, or plain HTTP.

Before you start

  • The edge server is running, by default on port 8081, and the flag express-checkout is deployed to Development. See Clients and edge server.
  • You have a client and its SDK key. Server code uses checkout-service, a Backend client. Browser code uses a Web client, because a browser sends an Origin header. In the story, that client is juniper-web.

FluxGate SDKs

FluxGate publishes SDKs for three ecosystems. All of them talk to the edge server over OFREP with an SDK key, so they work with any edge server that the Edge server API describes. Each one is open source under the Apache License 2.0.

SDKPackagesRegistrySource
Java and Spring Bootcom.forgeopslabs:fluxgate-java, com.forgeopslabs:fluxgate-spring-boot-starterMaven Centralforgeopslabs/fluxgate-springboot
TypeScript, React and Angular@forgeops/fluxgate, @forgeops/fluxgate-react, @forgeops/fluxgate-angularnpmforgeopslabs/fluxgate-js
Rustfluxgatecrates.ioforgeopslabs/fluxgate-rust

The SDKs share one behavior, so you can move between them without surprises:

  • Evaluations never throw. On any error, such as a network failure, a wrong SDK key or an unknown flag, you get your default value and an error code that says why.
  • The default value sets the type. A string default expects a string flag. Another type returns your default with TYPE_MISMATCH.
  • An off flag returns your default. A flag that is disabled or not deployed to the client's environment answers false with no variant. For a string or number flag, the SDKs return your default value without an error.
  • A targeting key is required. Without one, the SDKs return your default with TARGETING_KEY_MISSING and do not call the edge.
  • Retries, timeouts and a short cache. Network errors and HTTP 502, 503 and 504 are retried with backoff. Successful single-flag results are cached for 30 seconds per flag and context.
  • OpenFeature providers included. Each SDK has an OpenFeature provider, so code written against the OpenFeature API can use FluxGate without changes.

Each repository has samples with a Docker Compose file that starts its own FluxGate stack and a script that creates the flags, so you can try the SDK on your machine.

Which one to use

Your appUse
Spring Boot 3.5fluxgate-spring-boot-starter: properties, @FeatureToggle, metrics and a health indicator.
Java 17 or newer, without Springfluxgate-java.
Node.js 20 or newer@forgeops/fluxgate.
React 18 or newer@forgeops/fluxgate-react, with a Web client.
Angular 19 or newer@forgeops/fluxgate-angular, with a Web client.
Rust 1.85 or newerfluxgate, async on Tokio or with the blocking feature.
Any other languageAn OpenFeature SDK with the OFREP provider, below.
A script or a shellPlain HTTP.

OpenFeature with OFREP

OpenFeature is a vendor-neutral API for feature flags. OFREP, the OpenFeature remote evaluation protocol, is how an OpenFeature provider talks to a flag service over HTTP. The edge server speaks OFREP, so any language with an OpenFeature SDK works, even without a FluxGate SDK. You install the OpenFeature SDK for your language and its OFREP provider, and you point the provider at the edge.

Every example does the same four things:

  1. Create an OFREP provider with the edge's base URL, the root without a path, and the SDK key in the Authorization header.
  2. Register the provider with OpenFeature and wait until it is ready.
  3. Build an evaluation context with a targeting key and the attributes your rules use.
  4. Ask for the flag with a default value.
app.mjs
import { OpenFeature } from '@openfeature/server-sdk';
import { OFREPProvider } from '@openfeature/ofrep-provider';

await OpenFeature.setProviderAndWait(new OFREPProvider({
  baseUrl: 'http://localhost:8081',
  headers: [['Authorization', `Bearer ${process.env.FLUXGATE_SDK_KEY}`]],
}));

const client = OpenFeature.getClient();
const variant = await client.getStringValue('express-checkout', 'classic', {
  targetingKey: 'user-1',
  country: 'CA',
  user_tier: 'plus',
});
console.log(`checkout: ${variant}`);
await OpenFeature.close();
main.js
import { OpenFeature } from '@openfeature/web-sdk';
import { OFREPWebProvider } from '@openfeature/ofrep-web-provider';

const SDK_KEY = '<juniper-web SDK key>';

await OpenFeature.setContext({ targetingKey: 'user-1', country: 'CA', user_tier: 'plus' });
await OpenFeature.setProviderAndWait(new OFREPWebProvider({
  baseUrl: 'http://localhost:8081',
  headers: [['Authorization', `Bearer ${SDK_KEY}`]],
}));

const client = OpenFeature.getClient();
const variant = client.getStringValue('express-checkout', 'classic');
console.log(`checkout: ${variant}`);
App.java
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.openfeature.contrib.providers.ofrep.OfrepProvider;
import dev.openfeature.contrib.providers.ofrep.OfrepProviderOptions;
import dev.openfeature.sdk.Client;
import dev.openfeature.sdk.MutableContext;
import dev.openfeature.sdk.OpenFeatureAPI;

public class App {
    public static void main(String[] args) throws Exception {
        OfrepProviderOptions options = OfrepProviderOptions.builder()
            .baseUrl("http://localhost:8081")
            .headers(ImmutableMap.of(
                "Authorization", ImmutableList.of("Bearer " + System.getenv("FLUXGATE_SDK_KEY"))))
            .build();

        OpenFeatureAPI api = OpenFeatureAPI.getInstance();
        api.setProviderAndWait(OfrepProvider.constructProvider(options));

        Client client = api.getClient();
        MutableContext context = new MutableContext("user-1");
        context.add("country", "CA");
        context.add("user_tier", "plus");

        String variant = client.getStringValue("express-checkout", "classic", context);
        System.out.println("checkout: " + variant);
        api.shutdown();
    }
}

Node (server)

Install the server SDK and the OFREP provider. Save the first tab above as app.mjs. It is an ES module, so keep the .mjs extension.

Install
npm install @openfeature/server-sdk @openfeature/ofrep-provider
Run it
FLUXGATE_SDK_KEY=<checkout-service SDK key> node app.mjs
Output
checkout: express
  • Pass headers as a list of pairs, as above. A plain object fails when the provider starts, in the version below.
  • setProviderAndWait makes sure the provider is ready before the first evaluation.
  • The evaluation context sits in the third argument. targetingKey is the bucketing key. country and user_tier are the context attributes from Contexts.

Tested with @openfeature/server-sdk 1.23.0 and @openfeature/ofrep-provider 0.2.5, on Node 22.

To see the full answer, not only the value, ask for the details:

Evaluation details
const details = await client.getStringDetails('express-checkout', 'classic', {
  targetingKey: 'user-1',
  country: 'CA',
  user_tier: 'plus',
});
console.log(details);
Output
{
  value: 'express',
  variant: 'express',
  reason: 'TARGETING_MATCH',
  flagMetadata: {},
  flagKey: 'express-checkout'
}

Browser (web)

A browser app uses the OpenFeature web SDK. The web provider is different from the server provider: it fetches all flags for one context with the bulk endpoint, POST /ofrep/v1/evaluate/flags, and then answers evaluations from memory. When you change the context, it fetches again.

A browser sends an Origin header, so the SDK key must belong to a Web client, and the page origin must be in the client's Web Origins. In the story, juniper-web allows http://localhost:5173. The edge answers any other origin with 403. See CORS.

Install the web SDK and the web provider. Put the second tab above in your app's entry file, for example main.js in a Vite project, and replace the placeholder with the SDK key of the Web client.

Install
npm install @openfeature/web-sdk @openfeature/ofrep-web-provider

The console.log line prints this in the browser console:

Output
checkout: express
  • Set the context before the provider. The provider reads the context when it starts and sends it in the bulk request.
  • getStringValue is synchronous. It reads the result that the provider fetched.
  • The SDK key of a Web client is visible to anyone who opens the page. Use a Web client only for flags that are safe to show, and rely on Web Origins to limit which sites can use the key.

The provider's own documentation describes more options: polling with pollInterval, a localStorage cache with cacheMode, and a re-fetch when the tab becomes visible again.

Tested with @openfeature/web-sdk 1.10.0 and @openfeature/ofrep-web-provider 0.4.3 (@openfeature/core 1.12.0 installs with them), in a page served from http://localhost:5174 by a Vite dev server. The page's origin was the only entry in the Web client's Web Origins. The browser sent a preflight request, which returned 204, and then the bulk request, which returned 200.

Java with the OFREP provider

Add the OpenFeature Java SDK and the OFREP provider to your build. The third tab above holds App.java. Set FLUXGATE_SDK_KEY to the checkout-service SDK key in the environment of the process, then run the App class from your IDE or build tool.

pom.xml
<dependency>
  <groupId>dev.openfeature</groupId>
  <artifactId>sdk</artifactId>
  <version>1.23.0</version>
</dependency>
<dependency>
  <groupId>dev.openfeature.contrib.providers</groupId>
  <artifactId>ofrep</artifactId>
  <version>0.0.2</version>
</dependency>

The program prints:

Output
checkout: express

The MutableContext constructor takes the targeting key. The provider needs Guava for ImmutableMap. It comes as a dependency of the OFREP provider. Add com.google.guava:guava yourself if you want to pin its version.

Tested with dev.openfeature:sdk 1.23.0 and dev.openfeature.contrib.providers:ofrep 0.0.2, the latest release of the provider on Maven Central when this page was written. The example compiled with Maven for Java 17 on a JDK 25 build (Temurin 25.0.1), and it printed checkout: express against a real edge server.

Good to know about the OFREP providers

  • A failed evaluation does not throw. OpenFeature returns your default value. The details call shows why. With a wrong SDK key, errorCode is GENERAL and errorMessage is OFREP request failed: unauthorized. Check a new key with curl first.
  • A flag that is not deployed to the client's environment answers false with the reason DISABLED. A string flag then returns your default value, because false is not a string. The error code in the details is TYPE_MISMATCH.
  • An unknown flag key returns your default value with the error code FLAG_NOT_FOUND.
  • Use the same type as the flag's values. express-checkout has string variants, so call getStringValue. holiday-banner is an on/off flag, so call getBooleanValue.
  • An SDK key belongs to one client, and a client belongs to one environment. A Development key never sees Production rules.
  • The edge caches an accepted key for up to 300 seconds by default, so a rotated API key or a disabled client can keep working for that long.

Plain HTTP

If you use no SDK, send a POST request with curl or any HTTP client. A single-flag call looks like this:

No SDK
curl -s -X POST http://localhost:8081/ofrep/v1/evaluate/flags/express-checkout \
  -H "Authorization: Bearer $FLUXGATE_SDK_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"context":{"targetingKey":"user-1","country":"CA","user_tier":"plus"}}'
Response
{"key":"express-checkout","value":"express","reason":"TARGETING_MATCH","variant":"express"}

The Edge server API page describes the endpoints, the errors, CORS, and ETags in full.

Next

Pick your SDK: Java and Spring Boot, TypeScript, React and Angular, or Rust.