#dynamo-db #macro #create #struct #helper #aws #scan

dynamodb-helper

创建用于与AWS DynamoDB交互的结构体的宏

3个版本

0.1.2 2022年11月1日
0.1.1 2022年10月31日
0.1.0 2022年10月31日

1218过程宏

MIT 许可证

53KB
905

DynamoDB Helper

这个包提供了一个宏,该宏将生成一个用于与DynamoDB交互的结构体,而不需要通常所需的样板代码。

此项目类似于dynomite-derive 包。但是dynomite derive是基于一个非官方的Rust SDK rusoto,该SDK现在已经进入维护模式,而在这里使用的是官方SDK。

示例用法

use dynamodb_helper::DynamoDb;
use tokio_stream::StreamExt; // needed if the scan method is not excluded

#[derive(DynamoDb)]
struct ExampleStruct {
    #[partition]
    id: String,
    // other values
}

// thanks to the above derive, we can now create a db client
let db = ExampleStructDb::build(aws_sdk_dynamodb::Region::new("eu-west-1"), "exampleTable").await;

// the following will return an ExampleStruct if the id is found
let example_struct = db.get("someId".to_string()).await.expect("This one to exist");

#[derive(DynamoDb)]
struct OtherStruct {
    #[partition]
    id: String,
    #[range]
    range_id: String
    // other values
}

// alternative to build, we can use new and pass in a client
let other_db = OtherStructDb::new(a_dynamodb_client, "exampleTable");

// now we need to pass in both parts of the id
let other_struct = other_db.get("someId".to_string(), "someRange".to_string()).await.expect("This one to exist");
// or only the partition id, in which case we'll get back a Vec
let multiple_structs = other_db.get_by_partition_key("someId".to_string()).await.expect("This one to exist");

// and you can also put, delete, scan, etc.

还可以查看单元和集成测试。

请务必查看使用说明以及属性和方法概述

使用说明

依赖项

这些依赖项是必需的

aws-config = "0.47.0"
aws-sdk-dynamodb = "0.17.0"

以及可能还需要tokio-stream依赖项(见下文)

StreamExt特质

如果您收到关于以下特质的错误警告“以下特质界限未满足:impl futures_core::stream::Stream<Item = Result<...> + Unpin: Iterator”,这可能是由于您使用了生成的扫描方法,该方法需要以下特质在作用域内(将其添加到您的文件导入中)

use tokio_stream::StreamExt;

并添加tokio-stream依赖项。或者,您可以选择排除扫描方法的生成

宏细节

宏属性

  • #[partition]应装饰将用作分区/散列键的字段
  • #[range]可以可选放置在用作范围/排序键的字段上

生成的结构和方法

宏将实现以下特质

  • TryFrom<HashMap<String, AttributeValue>> 用于您的结构体(因为如果DynamoDB中的数据与预期不符,这可能会失败)
  • From<YourStruct> 用于 HashMap<String, AttributeValue> (应成功,因为它基于类型信息,尽管如果DynamoDB配置和数据不符合预期,可能会在后续失败)

宏还会生成一个名为带注释结构体名称加上后缀 Db 的结构体,具有以下方法(假设您的带注释结构体名为 ExampleStruct

  • fn new(client: aws_sdk_dynamodb::Client,table: &str) -> Self
  • asyncfn build(region: aws_sdk_dynamodb::Region,table: &str) -> Self
  • asyncfn create_table(&self) -> Result<CreateTableOutput, SdkError<CreateTableError>>
  • asyncfn create_table_with_provisioned_throughput(&self, read_capacity: i64, write_capacity: i64) -> Result<CreateTableOutput, SdkError<CreateTableError>>
  • asyncfn delete_table(&self) -> Result<DeleteTableOutput, SdkError<DeleteTableError>>
  • fn get(&self, partition: String) -> Result<Option<ExampleStruct>, ExampleStructDbGetError> (自定义错误)
  • fn get_by_partition_key(&self, partition: String) -> Result<Vec<ExampleStruct>, ExampleStructDbGetByPartitionError> (仅当您有复杂键时,例如分区加范围;自定义错误)
  • fn batch_get(&self, keys: Vec<String>) -> Result<Vec<ExampleStruct>, ExampleStructDbBatchGetError> (自定义错误)
  • async fn scan(&self) -> Result<Vec<ExampleStruct>, ExampleStructDbScanError> (自定义错误)
  • asyncfn put(&self, 输入:ExampleStruct) -> Result<PutItemOutput, SdkError<PutItemError>>
  • async fn batch_put(&self, items: Vec<ExampleStruct>) -> Result<BatchWriteItemOutput, SdkError<BatchWriteItemError>> (仅用于条目)
  • asyncfn delete(&self, 分区:String) -> Result<DeleteItemOutput, SdkError<DeleteItemError>>

创建表和删除表的函数适用于测试、原型和较小项目。对于真实应用,可能最好以IAC创建表,并将名称传递给new()build()

客户端和表名都作为公共字段公开,以防您还想使用这些字段进行自定义查询。

支持的类型

在您的结构体中,您可以使用以下类型

  • 数字
  • 字符串
  • 布尔值
  • Vec<String>
  • Vec<数字>
  • HashMap<String, String>

请注意,DynamoDB仅支持字符串、数字和布尔值作为键类型。

无法将它们保存为字符串集数字集,其他类型的map和vec仍在待办事项列表中。

错误

大多数方法返回一个结果,错误是适当的AWS错误。例如,create_table返回Result<aws_sdk_dynamodb::output::CreateTableOutput, aws_sdk_dynamodb::types::SdkError<aws_sdk_dynamodb::error::CreateTableError>>

检索方法(获取、批量获取和扫描)返回一个自定义错误,因为解析返回值可能会失败。返回的错误是解析错误和AWS错误的枚举。错误的名称基于结构体的名称。

例如,对于结构体ExampleStruct,我们的宏生成

pub enum ExampleStructDbScanError {
    ParseError(String),
    AwsError(aws_sdk_dynamodb::types::SdkError<aws_sdk_dynamodb::error::ScanError>),
}

并且扫描方法返回Result<Vec<ExampleStruct>, ExampleStructDbScanError>

排除

您可以决定不生成方法。这样做有各种原因

  • scan需要一个额外的导入和依赖
  • 一些代码可能太危险而无法公开(如delete_table
  • 更多的排除意味着生成的代码更少。例如,仅启用构建和获取,生成的代码量将减少约50%(15 kb)。
#[derive(DynamoDb)]
#[exclusion("scan", "delete_table", "create_table")]
pub struct ExampleTestStruct {
    #[partition]
    partition_key: String,
    value: i32,
}

“排除”接受以下参数:“new”、“build”、“get”(当适用时,也会排除get_by_partition_key),“batch_get”、“put”、“batch_put”、“delete”、“scan”、“create_table”和“delete_table”。

特性和错误仅在必要时生成。

依赖项

~27MB
~537K SLoC