Skip to main content
The nexus-openfeature-spring-boot artifact wraps NexusClient behind the OpenFeature Java SDK standard. Install it alongside the main starter when your team uses the OpenFeature API.

Installation

Register the provider

Usage

Per-user targeting

Pass a targeting key and the flag is evaluated for that identity, instead of returning the anonymous snapshot value:
Requires the AB Testing add-on on the project. Without it the provider serves the snapshot value and reports STATIC - the correct answer for a project with no per-user rules to apply - and stops calling the endpoint for five minutes. The throttle expires on its own, so activating the add-on takes effect with nothing to restart.

One request per identity, not per flag

The first targeted evaluation asks about every flag in the snapshot at once and memoises the answers, so the rest are served from memory: a request resolving twenty flags for a user makes one call. A flag set larger than the endpoint’s 200-key limit is split automatically. Concurrent evaluations for the same identity coalesce. The first caller fetches and the others wait on its result, so a burst of requests for one user does not become a burst of requests to the service. A flag the snapshot does not define is never sent: the endpoint answers false for a key it does not know, which is indistinguishable from “the flag exists and is off”, so sending it would override your true default while reporting a successful evaluation.

Reasons

Switch on the reason rather than on the value alone - it tells you what kind of answer you received.
STALE is emitted as a string literal, because the OpenFeature Java SDK’s Reason enum does not carry it although the specification defines it. Compare against "STALE".

Attributes are strings

Cohort conditions compare attribute values as strings, so a non-string context attribute is dropped and logged, never converted. No conversion is lossless, and a coerced value that then matches no rule is harder to diagnose than an absent one. The targeting key travels as the identity and is not repeated as an attribute.
A targeted boolean evaluation performs I/O on a memo miss. getBooleanEvaluation is synchronous in the OpenFeature Java API, so the calling thread blocks for one HTTP request. If a code path must not block, pass no targeting key - or call NexusClient.evaluateAB(...) directly, where the call is explicit.

Tuning

Every value is validated when the options are built and the failure names the option. Eviction takes expired entries first, then the entry closest to expiring.

Evaluation behaviour

An object resolves into the value model, not into JSON text, so asStructure() and asList() work on an object config - which is the whole point of an object evaluation. Nested objects and arrays are traversable, and a JSON null keeps its position rather than collapsing an array. An integer larger than the Value integer slot is carried as its exact decimal text (v0.13.0), at every depth of an object or array resolution. The structure the consumer asked for exists, so one oversized field must not cost the whole object - and a double would be a different number (9007199254740993 would read back as 9007199254740992). Read such a field with asString(). An integer that fits stays an integer and a genuinely fractional number stays a double. Numbers are not narrowed. getIntegerValue reports TYPE_MISMATCH for a value that is not an exact int: 2.9 is not 2, and 3000000000 is not what a narrowing conversion would produce for it. A whole-numbered value such as 5.0 is an integer, because JSON has a single number type. variant is the string form of the resolved value for scalar types - lowercase true / false for booleans - and absent on an object resolution, which has no short identifier to name.