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: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 answersfalse 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.Tuning
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.