
RustでMomentoのコレクションデータ型を試す
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Introduction
高速サーバレスキャッシュサービスMomentoの情報です。
最近のアップデートにより、コレクションデータ型がサポートされました。
今回はMomentoのRust用SDKを使って
コレクション型をつかったMomentoへのアクセスを試してみます。
[注意]
Momentoのコレクション機能は現在previewです。
2023年1月現在、この機能を使いたい場合は
support@momentohq.comに連絡する必要があるので
注意してください。
Environment
今回試した環境は以下のとおりです。
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 12.4
- Rust : 1.66.1
- Momento SDK : v0.21.0
DevIOのMomento関連記事はここにあるので、
これらもご確認おねがいします。
Setup
まずはMomentoのセットアップです。
このあたりを参考に、
Momentoの認証トークンを取得しましょう。
トークンを取得したらコンソールで環境変数にセットしておきます。
% export MOMENTO_AUTH_TOKEN = <取得した認証トークン>
次に、CargoをつかってRustプロジェクトの作成と依存ライブラリの設定です。
% cargo new momento-rust && cd momento-rust
# Cargo.toml
[dependencies]
momento = "0.21.0"
[dependencies.uuid]
version = "1.2.2"
features = [
    "v4",                
    "macro-diagnostics", 
]
Try
ではコレクションをつかってみましょう。
基本的にはJavaScript用SDKと似ているのですが、
言語的な違いがあったりするので多少は違います。
とりあえず必要モジュールのimportとクライアントの作成をするコードです。
use std::collections::HashMap;
use std::env;
use std::time::Duration;
use uuid::Uuid;
use momento::{
    MomentoResult,
    response::MomentoDictionaryGetResponse,
    response::MomentoDictionaryGetStatus, 
    response::CollectionTtl, 
    response::SimpleCacheClient,
    response::MomentoError,
    SimpleCacheClientBuilder,
};
fn get_client() -> SimpleCacheClient {
    let auth_token = env::var("MOMENTO_AUTH_TOKEN")
        .expect("env var MOMENTO_AUTH_TOKEN must be set to your auth token");
    let item_default_ttl_seconds = 60;
    SimpleCacheClientBuilder::new(auth_token, Duration::from_secs(item_default_ttl_seconds))
        .unwrap()
        .build()
}
Dictionary
クライアントを取得したり、元になるDictionaryを作ります。
    //Get Momento Client
    let mut momento = get_client();
    //Create Cache
    let cache_name = Uuid::new_v4().to_string();
    match momento.create_cache(&cache_name).await {
        Ok(_) => println!("ok"),
        Err(e1) =>println!("error occurred"),
    }
    //Create Dictionary & Dictionary Name
    let mut dictionary = HashMap::new();
    dictionary.insert("key1".to_string(), "value1".to_string());
    dictionary.insert("key2".to_string(), "10".to_string());
    dictionary.insert("key3".to_string(), "value3".to_string());
    let dictionary_name:String = Uuid::new_v4().to_string();
キャッシュ名とDictionary名を指定して、
dictionary_set関数でHashMapをキャッシュに登録します。
    momento
        .dictionary_set(
            &cache_name,
            &*dictionary_name, //or dictionary_name.clone()
            dictionary,
            CollectionTtl::default(),
        )
        .await;
登録したDictionaryから値の取得です。
Vecで任意の数のキーを指定して取得することもできます。
    let resp = momento
        .dictionary_get(&cache_name, &*dictionary_name, vec!["key1","key3"])
        .await
        .unwrap();
レスポンスは下記のように個別の値を取得できます。
    ////MomentoDictionaryGetResponse
    match resp.result  {
        MomentoDictionaryGetStatus::FOUND => {
            println!("dictionary found!");
            if let Some(dictionary) = &resp.dictionary {
                println!("dictionary entries:");
                for (k, v) in dictionary.iter() {
                    let k_str = String::from_utf8_lossy(k);
                    let v_str = String::from_utf8_lossy(v);
                    println!("0: {:?} => {:?}", k_str, v_str);
                }
            }        
        }
        MomentoDictionaryGetStatus::MISSING => println!("dictionary missing!"),
        _ => println!("error occurred"),
    };
dictionary_incrementを使えば引数に指定したキーの値を増やします。
 //key2の値を50増やす
 let value = momento
         .dictionary_increment(&cache_name, &*dictionary_name, "key2", 50, CollectionTtl::default())
         .await
         .expect("Failed to increment dictionary key")
         .value;
    println!("{}",value); //60
Dictionaryから値を削除するにはdictionary_deleteを使います。
    //remove some fields
    momento.dictionary_delete(
             &cache_name,
             &*dictionary_name,
             Fields::Some(vec!["key1"]),
         ).await.unwrap();
    // remove entire dictionary
    momento.dictionary_delete(
             &cache_name,
             &*dictionary_name,
             Fields::<Vec<u8>>::All,
         ).await.unwrap();
Set
次はSetを使ってみます。
set_union関数でキャッシュ名、セット名とコレクションを渡します。
    let elements = vec!["a", "b", "c", "a", "d"];
    momento
         .set_union(&cache_name, set_name.clone(), elements, CollectionTtl::default())
         .await
         .expect("error");
set_fetch関数を使えばSet全体を取得します。
    let response = momento
         .set_fetch(&cache_name, set_name.clone())
         .await
         .expect("Failed to fetch");
     if let Some(set) = response.value {
         println!("set entries:");
         for entry in &set {
             println!("{:?}", String::from_utf8_lossy(entry));
         }
     } else {
         println!("Collection not found");
     }
Summary
今回はRustでMomentoのコレクションAPIにアクセスしてみました。
JavaScript用SDKと同じく、簡単にコレクションAPIがつかえます。
なお、Rust用SDKは頻繁に更新されてますのでご注意ください。
この記事でキャッシュに使用したMomentoについてのお問い合わせはこちらです。
お気軽にお問い合わせください。
References
Momentoセミナーのお知らせ
2023年2月21日(火) 16:00からMomentoのセミナーを開催します。
興味があるかたはぜひご参加ください。












