smithy-lang / smithy-rs

Code generation for the AWS SDK for Rust, as well as server and generic smithy client generation.
Apache License 2.0
491 stars 187 forks source link

Constructors for constrained shapes that bypass validation #3833

Open david-perez opened 3 days ago

david-perez commented 3 days ago

Users have expressed interest in having a ConstrainedString::from_unchecked("invalid string") constructor that bypasses validation, either because they're absolutely sure that the data is valid or they have a reason to work with invalid data (for example, say a constraint is added to the model, and the service needs to return a value that was stored in the database prior to the model update; they want to grandfather-in these values).

drganjoo commented 3 days ago

Bypassing validation in the former case might be reasonable, particularly when dealing with data that has already been validated or persisted in a safe state and is now being loaded into the field. However, I disagree with the latter use case, where service teams bypass constraints because their model has evolved. Constraints in the model represent a clear contract with clients. Since smithy-rs clients do not enforce these constraints, introducing unchecked or invalid data into the API response risks breaking this contract. When a model evolves to include new constraints, these constraints often serve as guarantees of data integrity. Returning data that violates these new rules can lead to unpredictable client behavior, as clients assume that all returned data adheres to the updated model. This can cause cascading errors downstream if such data is processed without constraint checking.

I believe service teams should use a union type to differentiate between "conforming" and "legacy" data:

union ConstrainedResult {
    valid: ConstrainedString,
    legacy: String,
}