【お手軽】Cloudflare KVをNuxtで使ってみた
環境構築
地味にすごいポイントとして、公式のコマンドを実行するだけで環境を作れます。
追加でパッケージのインストールをする必要はありません。
Workerを作成
Cloudflare公式のコマンドを実行するだけで環境が作れます。
KVを作成
プロジェクトの作成が終わったらKVを作成します。
こちらもCloudflare公式のコマンドを順番に実行してください。
設定ファイル
KVを利用するにあたって設定ファイルを記述する必要があります。
環境構築の後にこれらを追加することでKVを利用できます。
wrangler.jsonc
nuxt.config.ts
{
// 他は省略
"kv_namespaces": [
{
"binding": "KV",
"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
]
}
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [
'nitro-cloudflare-dev',
],
nitro: {
preset: 'cloudflare_module',
// ここでKVの設定をする
storage: {
// ここのキーが後で紐付く
kv: {
driver: 'cloudflare-kv-binding',
binding: 'KV', // wrangler.jsonc のbindingと同じ
},
},
},
})
エンドポイント追加
KVを読み書きするエンドポイントを追加します。
/server/api
にエンドポイントを定義します。
ルーティングに関する公式ドキュメントはこちら
以下のようにCURDをするためのエンドポイントを作成します。
-| server/api/kv
---| index.get.ts # リスト
---| [key].get.ts # 検索
---| [key].put.ts # 追加・変更
---| [key].delete.ts # 削除
また、パラメータ部分に関してはわかりやすいようにh3-zod
で表現しています。
リスト
export default defineEventHandler(async (_event) => {
// nuxt.config.tsのstorageに設定したキーを引数に渡す
const storage = useStorage<string>('kv')
const keys = await storage.keys()
return { keys }
})
検索
import { zh } from 'h3-zod'
import { z } from 'zod'
export default defineEventHandler(async (event) => {
const { key } = await zh.useValidatedParams(event, z.object({
key: z.string(),
}))
const storage = useStorage<string>('kv')
const value = await storage.get(key)
return { value }
})
追加・更新
set()
はKVのメソッドであるput()
に該当します。
set()
にput()
で使われるオプションを第三引数に設定することができます。
オプションを設定することで有効期限とメタデータを追加できます。
import { zh } from 'h3-zod'
import { z } from 'zod'
export default defineEventHandler(async (event) => {
const { key } = await zh.useValidatedParams(event, z.object({
key: z.string(),
}))
const { value } = await zh.useValidatedBody(event, z.object({
value: z.string(),
}))
const storage = useStorage<string>('kv')
event.context.cloudflare.context.waitUntil(
// https://developers.cloudflare.com/kv/api/write-key-value-pairs/#put-method
storage.set(key, value, {
expirationTtl: 60,
metadata: {
myname: 'kojima',
},
}),
)
})
削除
import { zh } from 'h3-zod'
import { z } from 'zod'
export default defineEventHandler(async (event) => {
// bodyにしないよう注意
const { key } = await zh.useValidatedParams(event, z.object({
key: z.string(),
}))
const storage = useStorage<string>('kv')
event.context.cloudflare.context.waitUntil(
storage.del(key),
)
})
補足
Nuxt内で利用可能なuseStorage()
はNitroのユーティリティ関数であり、そのuseStorage()
はunstorageのAPIをラップしています。
unstorage自体もKVのメソッドをラップしているのでシンプルな使用感と引き換えにオリジナルで取得できる情報が削ぎ落とされています。
関係性としては以下のようになっています。
Nuxt > Nitro > unstorage > KV methods
例えば、put()
でメタデータを指定してもget()
ではメタデータが取得できません。
keys()
でキーの一覧を取得しても本来一緒に取得できるlist_complete
とcursor
は取得できません。
KVの機能をフルで活用したい場合は以下のようなユーティリティ関数を自作で追加するといいでしょう。
このようにすることで簡潔なAPIを維持したままKVの性能をフルに引き出せます。
import type { H3Event } from 'h3'
export default function useKV(event: H3Event) {
const kv = event.context.cloudflare.env.KV
return {
get: async (
key: string,
options?: Partial<KVNamespaceGetOptions<undefined>>,
) => {
return kv.getWithMetadata(key, options)
},
set: async (
key: string,
value: string | ArrayBuffer | ArrayBufferView | ReadableStream,
options?: KVNamespacePutOptions,
) => {
return await kv.put(key, value, options)
},
delete: async (key: string) => {
return await kv.delete(key)
},
list: async (options?: KVNamespaceListOptions) => {
return await kv.list(options)
},
}
}
サンプル
参考
Discussion