feat OpenFeature Provider (Dart)
OpenFeature provider for feat
feature flags. Wraps the feat Dart SDK to expose feat through the OpenFeature
API. It bridges the synchronous evaluation cache from feat_sdk to the
openfeature_dart_server_sdk
FeatureProvider interface.
Install
Add both the feat SDK and this provider to your pubspec.yaml:
dependencies:
feat_sdk: ^0.1.0
feat_openfeature: ^0.1.0
openfeature_dart_server_sdk: ^0.0.22
Usage
import 'package:feat_openfeature/feat_openfeature.dart';
import 'package:feat_sdk/feat_sdk.dart';
import 'package:openfeature_dart_server_sdk/open_feature_api.dart';
// 1. Construct and initialize the feat client.
final featClient = await FeatClient.initialize(
FeatClientConfig(
apiKey: 'feat_cs_...', // a client-side id or mobile key, never a server key
context: EvalContext.user('user-123'),
),
);
// 2. Register the provider with OpenFeature.
final api = OpenFeatureAPI();
await api.setProviderAndWait(FeatProvider(featClient));
// 3. Read flags through the OpenFeature client.
final client = api.getClient('my-app');
final enabled = await client.getBooleanFlag('checkout-v2', defaultValue: false);
How it works
- feat evaluates flags server side and
FeatClientcaches the resolved values, so each flag read is a synchronous cache lookup. The provider wraps every lookup in a completedFutureto satisfy the OpenFeature server SDK's async method signatures. - Type coercion: a flag that resolves to the wrong type returns the supplied
default with
ErrorCode.TYPE_MISMATCH; a flag that is not present returns the default withErrorCode.FLAG_NOT_FOUND. Numeric flags coerce betweenintanddouble(getIntegerFlag/getDoubleFlag). - Result mapping: feat's
EvaluatedFlag.variationIdmaps to the OpenFeature resultvariant, and feat's evaluationreasonmaps to the resultreason. trackis a no-op: the feat client SDK has no tracking API.
Async and static-context caveats
This is a server-paradigm OpenFeature provider (async method signatures), but feat's client is a static-context client: the context is set once and every flag is evaluated against it server side.
As a result, the per-evaluation context argument that OpenFeature passes to
each get*Flag call is ignored - honouring it would require a synchronous
re-evaluation against the network, which is not possible. To change the context,
use one of:
FeatProvider.setContext(EvalContext)- set a feat context directly.FeatProvider.setEvaluationContext(EvaluationContext)- set from an OpenFeature context (folded into feat's multi-context shape byfeatContextFrom).FeatClient.setContext(...)on the wrapped client.
Any of these re-polls feat and refreshes the cache; subsequent reads see the new values.
License
MIT
Libraries
- feat_openfeature
- An OpenFeature provider for feat.