Skip to main content

configdirector_openfeature_flutter_provider 0.1.0-beta.6 copy "configdirector_openfeature_flutter_provider: ^0.1.0-beta.6" to clipboard
configdirector_openfeature_flutter_provider: ^0.1.0-beta.6 copied to clipboard

OpenFeature provider for ConfigDirector on Flutter. ConfigDirector is a remote configuration and feature flag service.

ConfigDirector OpenFeature Provider for Flutter #

CI pub.dev

OpenFeature provider for ConfigDirector, remote config and feature flags with typed values, JSON Schema validation, and safe renames of live flags. Start free, no card required.

It plugs the ConfigDirector Flutter SDK into the OpenFeature Dart client SDK, the static-context SDK for client applications. It does not work with the OpenFeature Dart server SDK.

Install #

flutter pub add configdirector_openfeature_flutter_provider:^0.1.0-beta.6 openfeature_dart_client_sdk:^0.0.1-beta.1

The OpenFeature Dart client SDK is in beta, so the provider is published as a beta alongside it and both have to be asked for by version: pub never picks a pre-release on its own. Expect a new provider beta for each OpenFeature beta until they go stable together.

The OpenFeature Dart client SDK requires Dart 3.12.2, which ships with Flutter 3.44.2 and later.

Retrieve a value #

import 'package:configdirector_openfeature_flutter_provider/configdirector_openfeature_flutter_provider.dart';
import 'package:openfeature_dart_client_sdk/openfeature_dart_client_sdk.dart';

await OpenFeatureAPI.instance.setEvaluationContextAndWait(
  EvaluationContext(targetingKey: 'user-123'),
);
await OpenFeatureAPI.instance.setProviderAndWait(
  ConfigDirectorProvider(clientSdkKey: 'YOUR-CLIENT-SDK-KEY'),
);

final client = OpenFeatureAPI.instance.getClient();
final darkMode = client.getBooleanValue('dark-mode', false);

setProviderAndWait throws an OpenFeatureException when ConfigDirector cannot be reached in time. The provider keeps trying to connect and reports ready once it succeeds; until then flags resolve to their default values.

Evaluation context #

The OpenFeature evaluation context is sent to ConfigDirector as the context:

OpenFeature ConfigDirector
targetingKey, or else id id
kind kind
name name
traits, a structure traits
anonymous, a boolean anonymous

Any other attribute is ignored. Put the values your targeting rules depend on inside traits; a kind inside traits is an ordinary trait. Leaving kind out means user, and a context with an invalid kind is ignored as a whole: the SDK logs an error and flags resolve as if no context was set. The context handed to an individual evaluation is ignored as well: flags are evaluated against the context most recently set.

await OpenFeatureAPI.instance.setEvaluationContextAndWait(
  EvaluationContext(
    targetingKey: 'user-123',
    attributes: {
      'name': 'Ada',
      'traits': {'plan': 'pro'},
    },
  ),
);

Resolution details #

A flag ConfigDirector served resolves with the reason TARGETING_MATCH and the served value's id as its variant. One the config has no value for resolves to the default with the reason DEFAULT. Everything else is an error carrying the default: flagNotFound for an unknown key, providerNotReady before config state has arrived, and typeMismatch for a value that cannot be read as the requested type.

final details = client.getBooleanDetails('dark-mode', false);
if (details.errorCode == ErrorCode.providerNotReady) {
  // Config state has not arrived yet.
}

Test your code #

Tests of code that reads flags through OpenFeature swap the provider for the in-memory one the OpenFeature Dart client SDK ships, InMemoryProvider, so the test controls the values and nothing from ConfigDirector is involved:

import 'package:openfeature_dart_client_sdk/openfeature_dart_client_sdk.dart';

final provider = InMemoryProvider({'new-checkout': true, 'max-items': 20});
await OpenFeatureAPI.instance.setProviderAndWait(provider);
final client = OpenFeatureAPI.instance.getClient();

expect(client.getBooleanValue('new-checkout', false), isTrue);

provider.replaceAll({'new-checkout': false, 'max-items': 20});
expect(client.getBooleanValue('new-checkout', true), isFalse);

Shut OpenFeature down after each test with OpenFeatureAPI.instance.shutdown(). Full details are in the testing section of the official documentation.

Documentation #

Refer to the official documentation for the OpenFeature Flutter provider.

There is also a quickstart guide for ConfigDirector and any of our SDKs.

Getting Help #