Skip to content

Rust provider

Installation

Add the dependency in your Cargo.toml:

[dependencies]
open-feature-flagd = "0.0.4"
open-feature = "0.2"
Then integrate it into your application:

use open_feature_flagd::{FlagdOptions, FlagdProvider, ResolverType};
use open_feature::provider::FeatureProvider;
use open_feature::EvaluationContext;

#[tokio::main]
async fn main() {
    // Example using the REST resolver mode.
    let provider = FlagdProvider::new(FlagdOptions {
        host: "localhost".to_string(),
        port: 8016,
        resolver_type: ResolverType::Rest,
        ..Default::default()
    }).await.unwrap();

    let context = EvaluationContext::default().with_targeting_key("user-123");
    let result = provider.resolve_bool_value("bool-flag", &context).await.unwrap();
    println!("Flag value: {}", result.value);
}

Evaluation Modes

Remote Resolver (RPC)

In RPC mode, the provider communicates with flagd via gRPC. It supports features like streaming updates, retry mechanisms, and name resolution (including Envoy).

use open_feature_flagd::{FlagdOptions, FlagdProvider, ResolverType};
use open_feature::provider::FeatureProvider;
use open_feature::EvaluationContext;

#[tokio::main]
async fn main() {
    let provider = FlagdProvider::new(FlagdOptions {
        host: "localhost".to_string(),
        port: 8013,
        resolver_type: ResolverType::Rpc,
        ..Default::default()
    }).await.unwrap();

    let context = EvaluationContext::default().with_targeting_key("user-123");
    let bool_result = provider.resolve_bool_value("feature-enabled", &context).await.unwrap();
    println!("Feature enabled: {}", bool_result.value);
}

REST Resolver

In REST mode the provider uses the OpenFeature Remote Evaluation Protocol (OFREP) over HTTP. It is useful when gRPC is not an option.

use open_feature_flagd::{FlagdOptions, FlagdProvider, ResolverType};
use open_feature::provider::FeatureProvider;
use open_feature::EvaluationContext;

#[tokio::main]
async fn main() {
    let provider = FlagdProvider::new(FlagdOptions {
        host: "localhost".to_string(),
        port: 8016,
        resolver_type: ResolverType::Rest,
        ..Default::default()
    }).await.unwrap();

    let context = EvaluationContext::default().with_targeting_key("user-456");
    let result = provider.resolve_string_value("feature-variant", &context).await.unwrap();
    println!("Variant: {}", result.value);
}

In-Process Resolver

In-process evaluation is performed locally. Flag configurations are sourced via gRPC sync stream. This mode supports advanced targeting operators (fractional, semver, string comparisons) using the built-in evaluation engine.

use open_feature_flagd::{CacheSettings, FlagdOptions, FlagdProvider, ResolverType};
use open_feature::provider::FeatureProvider;
use open_feature::EvaluationContext;

#[tokio::main]
async fn main() {
    let provider = FlagdProvider::new(FlagdOptions {
        host: "localhost".to_string(),
        port: 8015,
        resolver_type: ResolverType::InProcess,
        selector: Some("my-service".to_string()),
        cache_settings: Some(CacheSettings::default()),
        ..Default::default()
    }).await.unwrap();

    let context = EvaluationContext::default()
        .with_targeting_key("user-abc")
        .with_custom_field("environment", "production")
        .with_custom_field("semver", "2.1.0");

    let dark_mode = provider.resolve_bool_value("dark-mode", &context).await.unwrap();
    println!("Dark mode enabled: {}", dark_mode.value);
}

File Mode

File mode is an in-process variant where flag configurations are read from a file. This is useful for development or environments without network access.

use open_feature_flagd::{FlagdOptions, FlagdProvider, ResolverType};
use open_feature::provider::FeatureProvider;
use open_feature::EvaluationContext;

#[tokio::main]
async fn main() {
    let file_path = "./path/to/flagd-config.json".to_string();
    let provider = FlagdProvider::new(FlagdOptions {
        host: "localhost".to_string(),
        resolver_type: ResolverType::File,
        source_configuration: Some(file_path),
        ..Default::default()
    }).await.unwrap();

    let context = EvaluationContext::default();
    let result = provider.resolve_int_value("rollout-percentage", &context).await.unwrap();
    println!("Rollout percentage: {}", result.value);
}

Configuration Options

Configurations can be provided as constructor options or via environment variables (with constructor options taking priority). The following options are supported:

Option Env Variable Type / Supported Value Default Compatible Resolver
Host FLAGD_HOST string "localhost" RPC, REST, In-Process, File
Port FLAGD_PORT number 8013 (RPC), 8016 (REST) RPC, REST, In-Process, File
Target URI FLAGD_TARGET_URI string "" RPC, In-Process
TLS FLAGD_TLS boolean false RPC, In-Process
Socket Path FLAGD_SOCKET_PATH string "" RPC
Certificate Path FLAGD_SERVER_CERT_PATH string "" RPC, In-Process
Cache Type (LRU / In-Memory / Disabled) FLAGD_CACHE string ("lru", "mem", "disabled") lru RPC, In-Process, File
Cache TTL (Seconds) FLAGD_CACHE_TTL number 60 RPC, In-Process, File
Max Cache Size FLAGD_MAX_CACHE_SIZE number 1000 RPC, In-Process, File
Offline File Path FLAGD_OFFLINE_FLAG_SOURCE_PATH string "" File
Retry Backoff (ms) FLAGD_RETRY_BACKOFF_MS number 1000 RPC, In-Process
Retry Backoff Maximum (ms) FLAGD_RETRY_BACKOFF_MAX_MS number 120000 RPC, In-Process
Retry Grace Period FLAGD_RETRY_GRACE_PERIOD number 5 RPC, In-Process
Event Stream Deadline (ms) FLAGD_STREAM_DEADLINE_MS number 600000 RPC
Offline Poll Interval (ms) FLAGD_OFFLINE_POLL_MS number 5000 File
Source Selector FLAGD_SOURCE_SELECTOR string "" In-Process