Skip to content

Add builder patterns to request structs across both libraries #38

@joshrotenberg

Description

@joshrotenberg

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 nested CloudProviderConfig - Essential for subscription creation
redis-enterprise crate:
  • EnterpriseClient - ✅ Already has builder
  • CreateDatabaseRequest - ✅ Already has CreateDatabaseRequestBuilder
  • CreateRoleRequest - 5 fields (4 optional) with complex nested Vec<BdbRole> - Important for permissions
  • CreateCrdbRequest - 6 fields (3 optional) with nested Vec<CreateCrdbInstance> - Critical for Active-Active
  • CreateMigrationRequest - 5 fields (3 optional) with nested MigrationEndpoint - 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

  1. Better Developer Experience: No more Some() wrapping or .to_string() calls
  2. Compile-time Validation: Required fields enforced at build time
  3. IDE Support: Better autocomplete and discoverability
  4. Consistency: Uniform API patterns across both crates
  5. Documentation: Method-level documentation for each builder field
  6. Extensibility: Easy to add new optional fields without breaking changes

Implementation Notes

  • Follow the existing CreateDatabaseRequestBuilder pattern in redis-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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions