Deno KVでステート管理を実装してみた話
はじめに
CLIのステート管理にDeno KVを使用してみたので、基本的な使い方や所感についてまとめた記事です。
Deno KVとは
Deno KVは、Denoに組み込まれたキーバリューストアです。SQLiteベースの実装でローカル開発では簡単に使え、Deno CLI や Deno Deploy でも同じAPIでスケールできる点が魅力的です。
特に以下の特徴があります。
- シンプルなAPI:
get
、set
、delete
、list
の基本操作(API Reference) - TypeScript対応: 型安全なデータ操作
- トランザクション:
複数操作のアトミック実行(Atomic Transactions) - Watch機能:
データ変更の監視(Watch API)
基本的な機能
Deno KVの基本的な機能について見ていきます。
KVストレージの初期化
const kv = await Deno.openKv(PATH);
KVストレージを開きます。引数にパスを提供することで、データベースはそのパスのディスクに永続化されます。
※パスが提供されない場合、データベースは現在のスクリプトのデフォルトパスで開かれます。
KVストレージへのデータ操作
const kv = await Deno.openKv(PATH);
const data: Hoge = {
value: "hoge",
};
await kv.set(["data", "key"], data);
set
メソッドでは、指定されたキーの値をデータベースに設定します。そのキーに対応する値が既に存在する場合は、上書きされます。
KVストレージからのデータ取得
const kv = await Deno.openKv(PATH);
const kvEntry = await kv.get<Hoge>(["data", key]);
指定されたキーの値とバージョンスタンプを、データベースから Deno.KvEntryMaybe の形式で取得します。
そのキーの値が存在しない場合、返されるエントリは NULL 値とバージョンスタンプを持ちます。
KVストレージからのデータ削除
const kv = await Deno.openKv(PATH);
await kv.delete(["data", key]);
。
指定されたキーの値をデータベースから削除します。そのキーに対応する値が存在しない場合、この操作は失敗します。
KVストレージのデータリスト
const kv = await Deno.openKv(PATH);
const kvEntries kv.list({ prefix: ["data"] });
データベース内のキーのリストを取得します。返されるリストは Deno.KvListIterator であり、データベースのエントリを繰り返し処理するために使用できます。
各リスト操作では、返すキーの範囲を指定するためのセレクタを指定しなければなりません。セレクタには、プレフィックスセレクタと範囲セレクタがあります。実装例では、prefix
オプションを使用して、特定のプレフィックスを持つキーのみをリストすることができます。
Tips
リソースの解放
Deno KVを使う際は、必ずkv.close()
でリソースを解放すること。
型安全性の活用
TypeScriptの型システムを活用することで、安全なデータ操作が可能です。
interface UserConfig {
theme: "light" | "dark";
language: string;
lastUpdated: Date;
}
const config = await kv.get<UserConfig>(["config", "user"]);
if (config.value) {
// TypeScriptが型を理解している
console.log(config.value.theme); // "light" | "dark"
}
必須の実行オプション
ドキュメントにも記載があるように、Deno KV は開発中のため変更される可能性があります。
現時点(2025年8月)では--unstable-kv
フラグを付けて実行する必要があります。
所感
Deno KVは、CLIツールにおいてステート管理を簡単に実装できる印象でした。
従来のファイルベースやデータベースを使った永続化に比べて、Deno KVはシンプルで使いやすく、特に小さなCLIツールのステート管理には適していると感じました。(特にDenoが利用できる環境であれば、すぐに使い始められます)
Denoエコシステムとの統合もされているので、他のDenoモジュールと組み合わせて使うことも容易な点や
SQLiteベースの実装であるため、ローカル開発環境でも手軽に使える所も魅力的に感じました。
Discussion