awslabs / aws-sdk-rust

AWS SDK for the Rust Programming Language
https://awslabs.github.io/aws-sdk-rust/
Apache License 2.0
2.96k stars 242 forks source link

Implementation of Struct Conversion to DynamoDB Attribute Item HashMap #1172

Open jonjsmith opened 1 month ago

jonjsmith commented 1 month ago

Describe the feature

Implement a utility in aws-sdk-rust that converts structs to DynamoDB attribute items. This feature aims to simplify the process of serializing Rust data structures into the format required by DynamoDB for storage and retrieval.

Use Case

I want to easily convert my Rust structs into DynamoDB attribute items so that I can efficiently store and retrieve complex data structures without manually handling each field's conversion or using 3rd party libraries.

Proposed Solution

Take a reference to a serializable struct and return a HashMap with String keys and AttributeValue values.

example usage

use aws_sdk_dynamodb::types::AttributeValue;
use aws_sdk_dynamodb::serde_conversion::to_dynamo_attribute_map;
use serde::{Serialize, Deserialize};
use std::collections::HashMap;

#[derive(Serialize, Deserialize, Debug)]
struct Address {
    street: String,
    city: String,
    zipcode: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Profile {
    bio: Option<String>,
    interests: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug)]
struct User {
    username: String,
    age: i64,
    active: bool,
    address: Address,
    profile: Profile,
    metadata: HashMap<String, String>,
}

fn main() {
    let user = User {
        username: "john_doe".to_string(),
        age: 30,
        active: true,
        address: Address {
            street: "123 Main St".to_string(),
            city: "Hometown".to_string(),
            zipcode: "12345".to_string(),
        },
        profile: Profile {
            bio: Some("Software developer and Rust enthusiast.".to_string()),
            interests: vec!["coding".to_string(), "reading".to_string(), "gaming".to_string()],
        },
        metadata: {
            let mut map = HashMap::new();
            map.insert("role".to_string(), "admin".to_string());
            map.insert("signup_date".to_string(), "2024-01-01".to_string());
            map
        },
    };

    // Convert to DynamoDB AttributeValue using Serde
    let attribute_item = to_dynamo_attribute_map(&user);
    println!("{:?}", attribute_item);
}

Other Information

I am not entirely sure if this feature is viable or a good approach. Therefore, I am very open to suggestions and improvements. Any feedback or advice on how to better implement this would be greatly appreciated

Acknowledgements

A note for the community

Community Note

landonxjames commented 1 month ago

Hi Jon, thanks for the feature request! Does the serde_dynamo crate cover your needs or is there something beyond that that the SDK could provide?

jonjsmith commented 1 month ago

Hi Landon,

Thank you for your response, I am not super familiar with serde_dynamo crate but I do see it covers what I am trying to implement here.

However, I was thinking about tighter integration directly within aws-sdk-rust. I think having built-in support for this conversion within the SDK would reduce the need for extra dependencies and ensure compatibility and consistency with the rest of the SDK. That being said, if you believe using serde_dynamo is the way to go, I am open to using it

landonxjames commented 1 month ago

For now serde_dynamo is definitely your best bet. This functionality likely wouldn't fit directly into the SDK itself, but into a higher level DDB library built on top of the SDK. We are working on our first HLL right now for S3, so those are definitely on our radar, but we are fairly resource constrained so one for DDB is not currently on our roadmap.

There is currently a feature in the works for better integration with serde decorators in our codegen. Technically this feature is a generic codegen thing and initially won't be enabled for the generated AWS SDKs. But if it would be useful we could discuss enabling it (perhaps behind a feature flag) for users.

rcoh commented 1 month ago

Just to clarify, the in progress feature is not exactly this. What is desired is actually an implementation of Serializer where the medium is dynamodb::AttributeValue — this is different than serializing an arbitrary struct to JSON which @jonjsmith is requesting.