Rust SDK 2.x to 3.0 migration guide

Overview

This topic explains how to adapt code that currently uses a 2.x version of the Rust server-side SDK to use version 3.0 or later.

Version 3.0 includes breaking changes. The most significant changes involve the HTTP transport layer, TLS/crypto feature flags, and some API refinements.

To learn more about the latest release, visit the SDK’s GitHub repository.

Understanding changes to Cargo features

The most impactful change in version 3.0 is the restructuring of Cargo feature flags. The default features have changed, and several new features have been introduced to give you more control over TLS backends and cryptographic implementations.

Here is a summary of the feature flag changes:

v2 Featurev3 FeatureNotes
rustls (default)hyper-rustls-native-roots (default)Renamed to clarify TLS backend and root certificate source
N/Ahyper-rustls-webpki-rootsNew option: uses rustls with bundled WebPKI root certificates
N/Anative-tlsNew option: uses the platform’s native TLS implementation
N/AhyperBase HTTP feature for hyper-based transports
N/Acrypto-aws-lc-rs (default)Cryptographic backend, previously always included
N/Acrypto-opensslNew alternative: uses OpenSSL for cryptographic operations
event-compression (opt-in)event-compression (default)Now enabled by default
Feature flag changes may affect compilation

If you previously relied on default features, your Cargo.toml may need updates. The renamed and restructured features mean that a version bump only may not compile without adjusting your feature configuration.

If you were using default features in v2.x, the defaults in v3.0 provide equivalent behavior. No changes to your Cargo.toml are needed in this case:

1[dependencies]
2launchdarkly-server-sdk = "2"

If you were explicitly enabling the rustls feature, update to the new feature name:

1[dependencies]
2launchdarkly-server-sdk = { version = "2", default-features = false, features = ["rustls"] }

You can also use alternative TLS or crypto backends:

1[dependencies]
2launchdarkly-server-sdk = { version = "3", default-features = false, features = ["hyper-rustls-webpki-roots", "crypto-aws-lc-rs"] }

Understanding the new transport layer

Version 3.0 introduces a new launchdarkly-sdk-transport crate that provides the HttpTransport trait. This trait abstracts the HTTP transport layer, replacing the previous approach of directly using hyper connectors.

The built-in implementation is HyperTransport. This is used by default when you enable any of the hyper-based features, including hyper-rustls-native-roots, hyper-rustls-webpki-roots, or native-tls.

If you were using the SDK with default settings and not customizing the HTTP connector, this change is transparent. The SDK automatically creates the appropriate HyperTransport based on your enabled features.

If you were providing a custom hyper connector, you now need to wrap it in a HyperTransport or implement the HttpTransport trait directly:

1use launchdarkly_server_sdk::ConfigBuilder;
2use hyper_rustls::HttpsConnectorBuilder;
3
4let connector = HttpsConnectorBuilder::new()
5 .with_native_roots()
6 .https_or_http()
7 .enable_http1()
8 .build();
9
10let config = ConfigBuilder::new("sdk-key")
11 .datasource_with_connector(&connector)
12 .build();

Understanding changes to data source configuration

The streaming and polling data source builders now use the HttpTransport trait instead of a generic connector type parameter.

The type signatures have changed:

  • StreamingDataSourceBuilder<C> is now StreamingDataSourceBuilder<T: HttpTransport>
  • PollingDataSourceBuilder<C> is now PollingDataSourceBuilder<T: HttpTransport>

The method for providing a custom transport has also been renamed:

  • .https_connector(connector) is now .transport(transport)

Here is an example:

1use launchdarkly_server_sdk::{ConfigBuilder, StreamingDataSourceBuilder};
2
3let builder = StreamingDataSourceBuilder::new()
4 .https_connector(my_connector);
5
6let config = ConfigBuilder::new("sdk-key")
7 .datasource(builder)
8 .build();

Understanding changes to event processor configuration

The event processor builder now uses the HttpTransport trait instead of a generic connector type parameter.

The type signature has changed:

  • EventProcessorBuilder<C> is now EventProcessorBuilder<T: HttpTransport>, with a default type parameter

The method for providing a custom transport has been renamed:

  • .https_connector(connector) is now .transport(transport)

Additionally, compress_events now defaults to true, while it defaulted to false in v2. If you previously relied on the default of no compression, you need to explicitly disable it.

Event compression and the Relay Proxy

If you are using the Relay Proxy, we recommend disabling event compression by setting .compress_events(false). Sending compressed events through the Relay Proxy causes unnecessary encoding, decoding, and re-encoding overhead.

Additionally, Relay Proxy versions prior to v8.9.0 cannot receive compressed events. If you are using a Relay Proxy version older than v8.9.0, you must disable event compression or upgrade your Relay Proxy.

Here is an example:

1use launchdarkly_server_sdk::{ConfigBuilder, EventProcessorBuilder};
2
3let builder = EventProcessorBuilder::new()
4 .https_connector(my_connector)
5 .compress_events(true); // had to opt in
6
7let config = ConfigBuilder::new("sdk-key")
8 .event_processor(builder)
9 .build();

Understanding changes to FlagDetailConfig

The FlagDetailConfig type has been updated. The client_side_only() method has been removed and replaced with a more flexible flag_filter method that accepts FlagFilter bitflags.

The new FlagFilter type supports:

  • FlagFilter::CLIENT filters for flags available to client-side SDKs. It replaces client_side_only().
  • FlagFilter::MOBILE filters for flags available to mobile SDKs. This is a new filter.

You can combine filters using the bitwise OR operator.

Here is an example:

1use launchdarkly_server_sdk::FlagDetailConfig;
2
3// Filter for client-side flags only
4let config = FlagDetailConfig::new()
5 .client_side_only();

Understanding changes to secure_mode_hash

The secure_mode_hash method’s return type has changed from String to Result<String, String>. This change reflects the fact that the cryptographic operation can fail.

Additionally, secure_mode_hash is now only available when either the crypto-aws-lc-rs or crypto-openssl feature is enabled.

Here is an example:

1use launchdarkly_server_sdk::Client;
2
3let hash: String = client.secure_mode_hash(&context);

Understanding changes to the EventProcessor trait

If you have implemented a custom EventProcessor, you need to add a new required method: flush_blocking. This method performs a synchronous flush of pending events with a timeout.

The signature is:

Flush blocking
1fn flush_blocking(&self, timeout: Duration) -> bool;

The method should trigger a flush of events currently in the outbox and block until that flush completes or the timeout expires. It returns true if the flush completed successfully, or false if it timed out.

Built-in implementations are already updated

If you are using the SDK’s built-in event processor or NullEventProcessor, no changes are required. This only affects custom EventProcessor trait implementations.