AWS SDK for Rustのα版を試してみた!

2021.05.08

本記事はAWS SDK for Rustのα版についての投稿です。α版はフィードバックを得るために公開されており、プロダクション環境での利用を想定したものではないので注意してください。

こんにちは、福岡オフィスのyoshihitohです。

本日、AWS SDK for Rust α版の立ち上げがアナウンスされました!

GitHubでリポジトリが公開されています。

Please Note: The SDK is currently released as an alpha and is intended strictly for feedback purposes only. Do not use this SDK for production workloads.

上記はREADMEからの引用です。GAになるまでは本番環境での利用は控えましょう。

利用者のフィードバックを集めるために公開されているものなので、早速試してみました!

検証環境

  • macOS: Mojave 10.14.6
  • Rust: 1.52.0
  • AWS SDK for Rust : v0.0.3-alpha

試すこと

α版ではDynamoDBのAPIがサポートされているので、テーブル作成(CreateTable)、アイテムの追加(PutItem)と取得(GetItem)を試してみます。

やってみる

プロジェクト作成

まずcargoコマンドでプロジェクトを作成します。

$ cargo new aws-sdk-for-rust-example
Created binary (application) `aws-sdk-for-rust-example` package

続いてCargo.tomlに依存クレートを設定します。

aws-sdk-dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.3-alpha"}
tokio = { version = "1", features = ["full"] }

AWS SDK for Rustを利用する準備ができたので、早速使っていきます。

クライアント作成

まず、DynamoDBのクライアントを作成します。環境変数に設定した認証情報を利用するため、 Client::from_env() を使います。

use aws_sdk_dynamodb as dynamodb;

#[tokio::main]
async fn main() -> Result<(), dynamodb::Error> {
    let client = dynamodb::Client::from_env();
    Ok(())
}

現時点では以下の環境変数設定に対応しているようです。

  • AWS_ACCESS_KEY_ID : アクセスキー
  • AWS_SECRET_ACCESS_KEY : シークレットキー
  • AWS_SESSION_TOKEN : セッショントークン

参考: https://github.com/awslabs/aws-sdk-rust/blob/main/sdk/aws-auth/src/provider.rs

テーブル作成 (CreateTable)

以下の内容でテーブルを作成します。

  • テーブル名: hello-rust-sdk
  • パティションキー: title (String)
  • ソートキー: なし
  • キャパシティ: オンデマンド
use dynamodb::model::AttributeValue;

async fn create_table(client: &dynamodb::Client) -> Result<(), dynamodb::Error> {
    client
        .create_table()
        .table_name("hello-rust-sdk")
        .attribute_definitions(
            dynamodb::model::attribute_definition::Builder::default()
                .attribute_name("title")
                .attribute_type(dynamodb::model::ScalarAttributeType::S)
                .build(),
        )
        .key_schema(
            dynamodb::model::key_schema_element::Builder::default()
                .attribute_name("title")
                .key_type(dynamodb::model::KeyType::Hash)
                .build(),
        )
        .billing_mode(dynamodb::model::BillingMode::PayPerRequest)
        .send()
        .await?;

    // NOTE:
    // 本来はDescribeTableで `TableStatus` が `ACTIVE` になるまで待機するべきです。
    // 今回は実装を簡素にするためsleepで代用しています。
    std::thread::sleep(std::time::Duration::from_secs(5));

    Ok(())
}

現時点ではFluent Interfaceを採用していて、初見でも使いやすかったです。リクエスト内容が確定したら、 .send() でリクエストを送信します。非同期メソッドなので、 .await を忘れないように気をつけましょう。

ソートキーを利用する場合は、 .attribute_definitions().key_schema() の呼び出しを追加してやると良さそうです。その他GSIやLSI、SSEなど、Create-Table APIで指定できるものは一通り対応しているようです。

アイテム追加 (PutItem)

titlecontent を文字列として登録します。

async fn put_item(
    client: &dynamodb::Client,
    title: &str,
    content: &str,
) -> Result<(), dynamodb::Error> {
    client
        .put_item()
        .table_name("hello-rust-sdk")
        .item("title", AttributeValue::S(title.to_string()))
        .item("content", AttributeValue::S(content.to_string()))
        .send()
        .await?;
    Ok(())
}

アイテム取得 (GetItem)

テーブルをスキャンして、 titlecontent を表示します。今回は1件だけしか登録していませんが、Limit指定も試してみます。

async fn show_items(client: &dynamodb::Client) -> Result<(), dynamodb::Error> {
    let res = client
        .scan()
        .table_name("hello-rust-sdk")
        .limit(10)
        .send()
        .await?;

    for item in res.items.unwrap_or_default() {
        if let (Some(AttributeValue::S(title)), Some(AttributeValue::S(content))) =
            (item.get("content"), item.get("content"))
        {
            println!("title: '{}', content: '{}'", title, content)
        }
    }

    Ok(())
}

各種操作を呼び出す

最後にmain関数を書き換えて、ここまでに実装した関数を呼び出します。

#[tokio::main]
async fn main() -> Result<(), dynamodb::Error> {
    let client = dynamodb::Client::from_env();

    // テーブルを作る
    create_table(&client).await?;

    // アイテムを追加する
    put_item(&client, "Hello, Rust SDK!", "This is very exciting!").await?;

    // アイテムを表示する
    show_items(&client).await?;

    Ok(())
}

ここまででコーディングはおしまいです、ビルドが通ることを確認したら動作確認に進みましょう!

$ cargo build
...
Compiling aws-sdk-for-rust-example v0.1.0 (/Users/yoshihitoh/workspace/projects/blog/rust/aws-sdk-for-rust/aws-sdk-for-rust-example)
    Finished dev [unoptimized + debuginfo] target(s) in 41.80s

動作確認

環境変数を設定して動かすだけなので、早速やってみましょう!

# 対象リージョン
export AWS_DEFAULT_REGION="ap-northeast-1"

# 認証情報
export AWS_ACCESS_KEY_ID="<YOUR ACCESS KEY>"
export AWS_SECRET_ACCESS_KEY="<YOUR SECRET ACCESS KEY>"
export AWS_SESSION_TOKEN="<YOUR SESSION TOKEN>"  # Assume Roleの場合に設定する

DynamoDBはリージョナルなサービスなので、 AWS_DEFAULT_REGION に対象リージョンを指定します。

DynamoDBの操作権限を持つIAMロールにAssumeRoleして、その認証情報を環境変数に設定してください。IAMユーザで操作する場合は AWS_SESSION_TOKEN の指定は不要です。

以上で環境変数の設定は完了です、動かしてみましょう!

$ cargo run
title: 'This is very exciting!', content: 'This is very exciting!'

問題なく動きましたね!AWSのコンソール上でも、テーブル作成・アイテム追加を確認できました

終わりに

ついに公式Rust SDKの立ち上げがアナウンスされました、多くの人が待ち望んでいたんじゃないでしょうか!まだα版ですが使い勝手が良く導入も簡単で、今後の開発が非常に楽しみです!!

プロダクション環境で利用することはできませんが、個人プロジェクトやツールなどで導入し、積極的にフィードバックしていきたいです!