Status: RFC
Applies to: client
For a summarized list of proposed changes, see the Changes Checklist section.
This RFC describes "Behavior Major Versions," a mechanism to allow SDKs to ship breaking behavioral changes like a new retry strategy, while allowing customers who rely on extremely consistent behavior to evolve at their own pace.
By adding behavior major versions (BMV) to the Rust SDK, we will make it possible to ship new secure/recommended defaults to new customers without impacting legacy customers.
The fundamental issue stems around our inability to communicate and decouple releases of service updates and behavior within a single major version.
Both legacy and new SDKs have the need to alter their SDKs default. Historically, this caused new customers on legacy SDKs to be subject to legacy defaults, even when a better alternative existed.
For new SDKs, a GA cutline presents difficult choices around timeline and features that can’t be added later without altering behavior.
Both of these use cases are addressed by Behavior Major Versions.
- Some Term: A definition for that term
In the current version of the SDK, users can construct clients without indicating any sort of behavior major version. Once this RFC is implemented, there will be three ways to set a behavior major version:
- In code via
aws_config::from_env_with_version(BehaviorMajorVersion::latest())
and<service>::Config::builder().behavior_major_version(...)
- By enabling
behavior-version-latest
in eitheraws-config
(which brings backfrom_env
) OR a specific generated SDK crate
# Cargo.toml
[dependencies]
aws-config = { version = "1", features = ["behavior-version-latest"] }
# OR
aws-sdk-s3 = { version = "1", features = ["behavior-version-latest"] }
If no BehaviorMajorVersion
is set, the client will panic during construction.
BehaviorMajorVersion
is an opaque struct with initializers like ::latest()
, ::v1()
. Downstream code can check the version by calling methods like ::supports_v1()
When new BMV are added, the previous version constructor will be marked as deprecated
. This serves as a mechanism to alert customers that a new BMV exists to allow them to upgrade.
In order to implement this feature, we need to create a BehaviorMajorVersion
struct, add config options to SdkConfig
and aws-config
, and wire it throughout the stack.
/// Behavior major-version of the client
///
/// Over time, new best-practice behaviors are introduced. However, these behaviors might not be backwards
/// compatible. For example, a change which introduces new default timeouts or a new retry-mode for
/// all operations might be the ideal behavior but could break existing applications.
#[derive(Debug, Clone)]
pub struct BehaviorMajorVersion {
// currently there is only 1 MV so we don't actually need anything in here.
}
We also will add BehaviorVersionLatestRuntimePlugin
, a runtime plugin that is enabled when the behavior-version-latest
feature is enabled in runtime crates.
To help customers migrate, we are including from_env
hooks that set behavior-version-latest
that are deprecated. This allows customers to see that they are missing the required cargo feature and add it to remove the deprecation warning.
An original design was also considered that made BMV optional and relied on documentation to steer customers in the right direction. This was deemed too weak of a mechanism to ensure that customers aren't broken by unexpected changes.
- Create
BehaviorMajorVersion
and the BMV runtime plugin - Add BMV as a required runtime component
- Wire up setters throughout the stack
- Add tests of BMV (set via aws-config, cargo features & code params)
- Remove
aws_config::from_env
deprecation stand-ins