-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
Add Builder Patterns to Request Structs
Overview
Currently, most request structs in both redis-cloud and redis-enterprise require verbose manual construction with explicit Some() wrapping for optional fields and .to_string() calls. This creates poor developer experience compared to a fluent builder API.
Current Problem
// Current verbose approach
let request = CreateDatabaseRequest {
name: "example-db".to_string(),
memory_limit_in_gb: 0.1,
data_persistence: "none".to_string(),
replication: false,
data_eviction: Some("volatile-lru".to_string()),
password: None,
support_oss_cluster_api: Some(false),
use_external_endpoint_for_oss_cluster_api: None,
};Proposed Solution
// Proposed fluent builder approach
let request = CreateDatabaseRequest::builder()
.name("example-db")
.memory_limit_in_gb(0.1)
.data_persistence("none")
.replication(false)
.data_eviction("volatile-lru")
.support_oss_cluster_api(false)
.build()?;Implementation Strategy
1. Use Proc Macro for Consistency
Add typed-builder or derive_builder dependency to ensure consistent builder patterns across both crates.
2. Standardize Existing Patterns
The redis-enterprise crate already has excellent builder implementation with CreateDatabaseRequestBuilder. Use this as the template for consistency.
3. Priority Implementation Order
HIGH Priority (Complex with multiple optionals/nested structures)
redis-cloud crate:
-
CloudClient- ✅ Already has builder -
CreateDatabaseRequest- 6 fields (4 optional) - Critical for database creation -
UpdateDatabaseRequest- 6 fields (all optional) - Important for database updates -
CreateSubscriptionRequest- 5 fields with complex nestedCloudProviderConfig- Essential for subscription creation
redis-enterprise crate:
-
EnterpriseClient- ✅ Already has builder -
CreateDatabaseRequest- ✅ Already hasCreateDatabaseRequestBuilder -
CreateRoleRequest- 5 fields (4 optional) with complex nestedVec<BdbRole>- Important for permissions -
CreateCrdbRequest- 6 fields (3 optional) with nestedVec<CreateCrdbInstance>- Critical for Active-Active -
CreateMigrationRequest- 5 fields (3 optional) with nestedMigrationEndpoint- Important for migrations
MEDIUM Priority (Multiple fields or all-optional)
redis-cloud crate:
-
CreatePeeringRequest- 6 fields (1 optional) - VPC peering setup -
UpdateSubscriptionRequest- 3 fields (all optional) - Subscription updates
redis-enterprise crate:
-
CreateUserRequest- 5 fields (2 optional) - User management -
UpdateUserRequest- 4 fields (all optional) - User updates -
BootstrapRequest- 3 nested structures - Cluster bootstrap
LOW Priority (Simple structures)
redis-cloud crate:
-
CreateBackupRequest- Only 2 fields (1 optional) - Simple backup creation
redis-enterprise crate:
- Various simple request structs with 1-3 fields
Benefits
- Better Developer Experience: No more
Some()wrapping or.to_string()calls - Compile-time Validation: Required fields enforced at build time
- IDE Support: Better autocomplete and discoverability
- Consistency: Uniform API patterns across both crates
- Documentation: Method-level documentation for each builder field
- Extensibility: Easy to add new optional fields without breaking changes
Implementation Notes
- Follow the existing
CreateDatabaseRequestBuilderpattern inredis-enterprise - Add validation where appropriate (e.g., memory limits, valid enum values)
- Provide sensible defaults for common optional fields
- Ensure builders work well with the existing handler patterns
- Add comprehensive examples showing the improved ergonomics
Dependencies to Add
[dependencies]
typed-builder = "0.18" # or derive_builder = "0.20"Definition of Done
- All HIGH priority request structs have builders
- Builder patterns are consistent across both crates
- Documentation examples updated to show builder usage
- Tests added for builder validation
- README examples updated with new builder patterns
This will significantly improve the developer experience and make the Redis APIs more idiomatic Rust.
Metadata
Metadata
Assignees
Labels
No labels