TypeScript x Momento | Node.js SDK でキャッシュを操作する
Momento Cache
今、勢いのあるサーバーレスのキャッシュサービスで、圧倒的な高速性と使いやすさが売りです。
Momento Cacheは、世界初の真のサーバーレスキャッシングサービスです。瞬時の弾力性、scale-to-zero機能、圧倒的な高速パフォーマンスを提供します。 容量の選択、管理、プロビジョニングが必要な時代は終わりました。Momento Cacheでは、SDKを入手し、エンドポイントを取得し、コードに数行入力するだけで、すぐに実行できます。
コンソールにログインして、すぐにキャッシュを扱うことができます。
本当にシンプルで簡単にサーバーレスの恩恵を受けることができます🙌
client-sdk-javascript
Node.js 用の SDK があるので、
TypeScript で Momento Cache を扱うサンプルコードを実装してみたいと思います。
Node.js SDK でキャッシュを操作する
キャッシュの作成
Momento コンソール にログインして、キャッシュを作成します。
また、API キーページ で API キーを発行します。
セットアップ
サンドボックス用のプロジェクトを作成します。
mkdir momento-node-sandbox
cd momento-node-sandbox
npm init -y
npm i -D typescript tsx
npx tsc --init
touch index.ts
echo "MOMENTO_API_KEY=" > .env
.env ファイルを扱うために @dotenvx/dotenvx もインストールします。
npm i @dotenvx/dotenvx
npm i @gomomento/sdk
MOMENTO_API_KEY
に API キーを定義しておきます。
文字列の Set と Get
基本であろう、文字列の Set と Get を確認します。
import { CacheClient, CacheGet, Configurations, CredentialProvider } from "@gomomento/sdk";
const CACHE_NAME = 'momento-sandbox';
// キャッシュクライアントの生成
const genClient = async () => {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 300,
});
};
console.log('Set and Get...');
genClient().then(async (client) => {
// キャッシュをセットする
await client.set(CACHE_NAME, 'my_key', 'hello, world!!!!');
// キャッシュを取得する
const result = await client.get(CACHE_NAME, 'my_key');
if (result instanceof CacheGet.Hit) {
console.log(result);
console.log(result.valueString());
} else if (result instanceof CacheGet.Miss) {
console.log(result);
} else if (result instanceof CacheGet.Error) {
console.error(result);
}
// キャッシュを削除する
await client.delete(CACHE_NAME, 'my_list_key');
}).catch((error) => {
console.error(error);
});
以下のコマンドを実行して、テストします!
% npx dotenvx run -- npx tsx index.ts
[dotenvx@0.43.2] injecting env (1) from .env
Set and Get...
Hit {
body: Uint8Array(11) [
72, 101, 108, 108,
111, 95, 119, 111,
114, 108, 100
]
}
Hello_world
無事に取得できました👏👏👏
defaultTtlSeconds
を指定しているので、キャッシュデータの TTL は 300 秒です。
valueString メソッドを使うことで、データをバイト配列からデコードした utf-8 文字列で返してくれます。
また、 CacheGet.Miss は TTL を超過してデータを取得できない場合も含まれるので、エラーとして処理しない方が望ましいでしょう。
Lists(配列)の操作
配列の連結
配列の末尾もしくは先頭に配列を連結することができます。
- ListConcatenateBack:末尾に要素を追加する
- ListConcatenateFront:先頭に要素を追加する
console.log('Lists...');
genClient().then(async (client) => {
// 配列をセットする
await client.listConcatenateBack(CACHE_NAME, 'my_list_key', ["a", "b", "c"]);
// 末尾に配列を連結する
await client.listConcatenateBack(CACHE_NAME, 'my_list_key', ["d", "e", "f"]);
// 先頭に配列を連結する
await client.listConcatenateFront(CACHE_NAME, 'my_list_key', ["g", "h", "i"]);
// キャッシュを取得する
const result = await client.listFetch(CACHE_NAME, 'my_list_key');
if (result instanceof CacheListFetch.Hit) {
console.log(result);
console.log(result.valueListString());
} else if (result instanceof CacheListFetch.Miss) {
console.log(result);
} else if (result instanceof CacheListFetch.Error) {
console.error(result);
}
// キャッシュを削除する
await client.delete(CACHE_NAME, 'my_list_key');
}).catch((error) => {
console.error(error);
});
実行結果です。
% npx dotenvx run -- npx tsx index.ts
[dotenvx@0.43.2] injecting env (1) from .env
Lists...
Hit {
_values: [
Uint8Array(1) [ 103 ],
Uint8Array(1) [ 104 ],
Uint8Array(1) [ 105 ],
Uint8Array(1) [ 97 ],
Uint8Array(1) [ 98 ],
Uint8Array(1) [ 99 ],
Uint8Array(1) [ 100 ],
Uint8Array(1) [ 101 ],
Uint8Array(1) [ 102 ]
]
}
[
'g', 'h', 'i',
'a', 'b', 'c',
'd', 'e', 'f'
]
配列の要素の削除
配列の末尾もしくは先頭の要素を削除することができます。
- ListPopBack:末尾に要素を削除する
- ListPopFront:先頭に要素を削除する
console.log('Lists...');
genClient().then(async (client) => {
// 配列をセットする
await client.listConcatenateBack(CACHE_NAME, 'my_list_key', ["a", "b", "c"]);
// 末尾に要素を削除する
const listPopBackResult = await client.listPopBack(CACHE_NAME, 'my_list_key');
if (listPopBackResult instanceof CacheListPopBack.Hit) {
console.log(listPopBackResult);
console.log(`Removed value: ${listPopBackResult.valueString()}`);
}
// 先頭に要素を削除する
const listPopFrontResult = await client.listPopFront(CACHE_NAME, 'my_list_key');
if (listPopFrontResult instanceof CacheListPopFront.Hit) {
console.log(listPopFrontResult);
console.log(`Removed value: ${listPopFrontResult.valueString()}`);
}
// キャッシュを取得する
const result = await client.listFetch(CACHE_NAME, 'my_list_key');
if (result instanceof CacheListFetch.Hit) {
console.log(result);
console.log(result.valueListString());
} else if (result instanceof CacheListFetch.Miss) {
console.log(result);
} else if (result instanceof CacheListFetch.Error) {
console.error(result);
}
// キャッシュを削除する
await client.delete(CACHE_NAME, 'my_list_key');
}).catch((error) => {
console.error(error);
});
実行結果です。
listPopBack
と listPopFront
は、返り値に削除された要素を持っています。
% npx dotenvx run -- npx tsx index.ts
[dotenvx@0.43.2] injecting env (1) from .env
Lists...
Hit { body: Uint8Array(1) [ 99 ] }
Removed value: c
Hit { body: Uint8Array(1) [ 97 ] }
Removed value: a
Hit { _values: [ Uint8Array(1) [ 98 ] ] }
[ 'b' ]
配列に要素を追加する
配列に要素を追加することができます。
- ListPushBack:末尾に要素を追加する
- ListPushFront:先頭に要素を追加する
ListConcatenateBack や ListConcatenateFront との違いは、追加する対象が配列か単一の要素かです。
console.log('Lists...');
genClient().then(async (client) => {
// 配列をセットする
await client.listConcatenateBack(CACHE_NAME, 'my_list_key', ["a", "b", "c"]);
// 末尾に要素を追加する
const listPopBackResult = await client.listPushBack(CACHE_NAME, 'my_list_key', "d");
if (listPopBackResult instanceof CacheListPushBack.Success) {
console.log(listPopBackResult);
console.log(`List length: ${listPopBackResult.listLength()}`);
}
// 先頭に要素を追加する
const listPopFrontResult = await client.listPushFront(CACHE_NAME, 'my_list_key', "e");
if (listPopFrontResult instanceof CacheListPushFront.Success) {
console.log(listPopFrontResult);
console.log(`List length: ${listPopFrontResult.listLength()}`);
}
// キャッシュを取得する
const result = await client.listFetch(CACHE_NAME, 'my_list_key');
if (result instanceof CacheListFetch.Hit) {
console.log(result);
console.log(result.valueListString());
} else if (result instanceof CacheListFetch.Miss) {
console.log(result);
} else if (result instanceof CacheListFetch.Error) {
console.error(result);
}
// キャッシュを削除する
await client.delete(CACHE_NAME, 'my_list_key');
}).catch((error) => {
console.error(error);
});
実行結果です。
listPushBack
と listPushFront
は、返り値に追加後の配列の長さを持っています。
% npx dotenvx run -- npx tsx index.ts
[dotenvx@0.43.2] injecting env (1) from .env
Lists...
Success { _list_length: 4, is_success: true }
List length: 4
Success { _list_length: 5, is_success: true }
List length: 5
Hit {
_values: [
Uint8Array(1) [ 101 ],
Uint8Array(1) [ 97 ],
Uint8Array(1) [ 98 ],
Uint8Array(1) [ 99 ],
Uint8Array(1) [ 100 ]
]
}
[ 'e', 'a', 'b', 'c', 'd' ]
指定した要素を削除する
指定した要素を削除することができます。
- ListRemoveValue:指定した要素を削除する
console.log('Lists...');
genClient().then(async (client) => {
// 配列をセットする
await client.listConcatenateBack(CACHE_NAME, 'my_list_key', ["a", "b", "c"]);
// 指定した要素を削除する
const listPopBackResult = await client.listRemoveValue(CACHE_NAME, 'my_list_key', "b");
if (listPopBackResult instanceof CacheListRemoveValue.Success) {
console.log(listPopBackResult);
console.log(`isSuccess: ${listPopBackResult.is_success}`);
}
// キャッシュを取得する
const result = await client.listFetch(CACHE_NAME, 'my_list_key');
if (result instanceof CacheListFetch.Hit) {
console.log(result);
console.log(result.valueListString());
} else if (result instanceof CacheListFetch.Miss) {
console.log(result);
} else if (result instanceof CacheListFetch.Error) {
console.error(result);
}
// キャッシュを削除する
await client.delete(CACHE_NAME, 'my_list_key');
}).catch((error) => {
console.error(error);
});
実行結果です。
% npx dotenvx run -- npx tsx index.ts
[dotenvx@0.43.2] injecting env (1) from .env
Lists...
Success { is_success: true }
isSuccess: true
Hit { _values: [ Uint8Array(1) [ 97 ], Uint8Array(1) [ 99 ] ] }
[ 'a', 'c' ]
まとめ
今回は Momento Cache でシンプルな文字列と配列をキャッシュするサンプルコードを書いてみました。
他にも、辞書型や Sorted sets という型も扱えます。
Sorted setsは、値(文字列)とスコア(符号付きダブル64ビットフロート)のペアを持つユニークな要素のコレクションです。項目の要素はスコア値順に並べられます。
気になる方は、ぜひ触ってみてください🔥
今回のソースコードは Github にも置いてあります。
Discussion