feat.so


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 FeatClient caches the resolved values, so each flag read is a synchronous cache lookup. The provider wraps every lookup in a completed Future to 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 with ErrorCode.FLAG_NOT_FOUND. Numeric flags coerce between int and double (getIntegerFlag / getDoubleFlag).
  • Result mapping: feat's EvaluatedFlag.variationId maps to the OpenFeature result variant, and feat's evaluation reason maps to the result reason.
  • track is 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 by featContextFrom).
  • 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.