Skip to content

raiden-rs/raiden-dynamo

Repository files navigation

DynamoDB library for Rust.


Continuous Integration

Examples

You can see more examples here

Generating client

raiden uses aws-sdk-dynamodb or rusoto_dynamodb as internal client.

With aws-sdk-dynamodb (aws-sdk is enabled)

use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

#[tokio::main]
async fn main() {
    // Simply, specify the region.
    let client = User::client(config::Region::from_static("us-east-1"));

    // You can also specify aws-sdk-dynamodb client.
    let client = {
        let sdk_config = aws_config::defaults(aws_config::BehaviorVersion::latest())
            .region(raiden::config::Region::from_static("us-east-1"))
            .load()
            .await;
        let sdk_client = raiden::Client::new(&sdk_config);

        User::client_with(sdk_client)
    };

    // Run operations...
}

With rusoto_dynamodb ( rusoto or rusoto_rustls or rustls is enabled)

use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

#[tokio::main]
async fn main() {
    // Simply, specify the region.
    let client = User::client(Region::UsEast1);

    // You can also specify rusoto_core client.
    let client = User::client_with(Client::shared(), Region::UsEast1);

    // Run operations...
}

Set prefix/suffix to the table name

use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

#[tokio::main]
async fn main() {
    let client = User::client(config::Region::from_static("us-east-1"))
        .table_prefix("prefix-")
        .table_suffix("-suffix");

    // Print `prefix-user-suffix`
    println!("{}", client.table_name());
}

Configure retry strategy

NOTE: Default retry strategy differs between aws-sdk and rusoto ( or rusoto_rustls )

  • aws-sdk ... Not retry in raiden by default. Because you can configure retry strategy using aws_config. Or you can configure your own strategy like next example.
  • rusoto or rusoto_rustls ... Enabled retrying in raiden by default. See detail here.
use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

// Force retry 3 times.
struct MyRetryStrategy;

impl RetryStrategy for MyRetryStrategy {
    fn should_retry(&self, _error: &RaidenError) -> bool {
        true
    }

    fn policy(&self) -> Policy {
        Policy::Limit(3)
    }
}

#[tokio::main]
async fn main() {
    let client = User::client(config::Region::from_static("us-east-1"))
        .with_retries(Box::new(MyRetryStrategy));

    // Run operations...
}

Running operations

get_item

use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

#[tokio::main]
async fn main() {
    let client = /* generate client */;
    let _res = client.get("user_primary_key").run().await;
}

put_item

use raiden::*;

#[derive(Raiden)]
#[raiden(table_name = "user")]
pub struct User {
    #[raiden(partition_key)]
    id: String,
    name: String,
}

#[tokio::main]
async fn main() {
    let client = /* generate client */;
    let input = User::put_item_builder()
        .id("foo".to_owned())
        .name("bokuweb".to_owned())
        .build();
    let _res = client.put(&input).run().await;
}

batch_get_item

use raiden::*;

#[derive(Raiden, Debug, PartialEq)]
pub struct User {
    #[raiden(partition_key)]
    id: String,
    #[raiden(sort_key)]
    year: usize,
}

#[tokio::main]
async fn main() {
    let client = /* generate client */;
    let keys: Vec<(&str, usize)> = vec![("Alice", 1992), ("Bob", 1976), ("Charlie", 2002)];
    let res = client.batch_get(keys).run().await;
}

Support tokio-rs/tracing

raiden supports making span for Tracing ( span name is dynamodb::action with table name and api name in field ).
To activate this feature, you need to specify tracing feature in your Cargo.toml. And your crate needs tracing .

# Example
[dependencies]
raiden = {
    tag = "0.0.76",
    git = "https://github.com/raiden-rs/raiden-dynamo.git",
    features = [ "tracing"]
}
tracing = "0.1"

Development

Requirements

  • Rust (1.76.0+)
  • Deno (1.13.2+)
  • GNU Make
  • Docker Engine

Run tests

make test

NOTE: Don't recommend to use cargo test because our test suite doesn't support running tests in parallel. Use cargo test -- --test-threads=1 instead of it.

Run examples

make dynamo

AWS_ACCESS_KEY_ID=dummy AWS_SECRET_ACCESS_KEY=dummy cargo run --example EXAMPLE_NAME

Utility

dynamodb-admin is useful to check data in DynamoDB Local.

npx dynamodb-admin

Then open http://localhost:8001 in browser.

Supported APIs

Item

  • BatchGetItem
  • BatchWriteItem
  • DeleteItem
  • GetItem
  • PutItem
  • Query
  • Scan
  • TransactGetItems
  • TransactWriteItems
  • UpdateItem

Known limitations

Here is a list of unsupported features/behaviors in the actual implementation. We have a plan to resolve these issues in a future release.

  • Automatic retrying: #44
  • Strict type checking of keys: #26
  • Exponential backoff handling

License

This project is available under the terms of either the Apache 2.0 license or the MIT license.

About

[WIP] ⚡️ DynamoDB library for Rust.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Contributors 19