
Node 'redis'ライブラリを使用してVercel KVに接続する方法
Vercel KV(Key-Value)は Vercel の新しいサービスで、サーバーレスのキーバリューストアを手軽に使えます。Upstash の Redis 機能を利用して Redis の上に作られており、これを操作するための Node ライブラリ /kv も Vercel が出しています。NextJS のサーバーレスエッジ関数の中でキーバリューストレージを使うなら、/kvがちょうどいいでしょう。
なぜ /kv だけを使わないの?
正確に言えば、必要な Redis の機能がライブラリで使える限りはちょうどいい、ということです。Vercel KV の裏側にあるのは完全な Redis インスタンスで、Redis クライアントプロトコル v6.2 までに対応しています。ただ、ライブラリのほうは、その Redis インスタンスで使える機能を全部実装しているとは限りません。
ライブラリの機能で足りるなら、そのまま使ったほうが楽です。足りない場合も心配はいりません。Vercel KV の中身はただの Redis インスタンスなので、redis(好みの他の Redis ライブラリでも構いません)から直接つなげます。
手順自体はとても簡単です。ただ、これについて書いた記事がネットで見つからなかったので、自分でまとめておくことにしました。
料金体系
本題に入る前に、Vercel KV の料金体系には目を通しておいてください。従量課金制で安く、使い方によっては月 1 ドル程度で収まることもあります。ただ価格は変わる可能性があるので、実際の金額は自分で確かめておくのがおすすめです。
Vercel KV のセットアップ
新しい Vercel KV のストレージを作るところから始めます。Vercel にログインしたら、トップメニューの「Storage」をクリックします。作成できるストレージがいくつか表示されるはずです。

データベース名とリージョンを入力するダイアログが出ます。入力して進めると、作成された Vercel KV の Redis インスタンスが表示されます!

「Show Secret」をクリックすると、次の文字列が出てきます。redis-cliコマンドラインツールから Redis インスタンスに接続するときに使うものです。
redis-cli --tls -u redis://default:597961c4b7344b5f9ce9691ae5fb8bd4@dear-chigger-38419.upstash.io:38419
注目するのは -u の後ろの部分です。これが Redis の接続文字列で、後でredisnode ライブラリからインスタンスに接続するときに使います。安全な場所にコピーしておいてください。
既存の NextJS プロジェクトに Redis を追加する
ここでは既存のプロジェクトに追加することを前提としています。もしそうでない場合は、NextJS の入門ガイドに従ってください。セットアップに特別な手順は必要ありません。
NextJS プロジェクトができたら、redisライブラリをインストールしましょう。
npm i redis
環境変数
先ほど安全な場所にコピーした接続文字列を、redisから読めるようにします。.env.localに環境変数を次のように追加してください。
REDIS_URL=redis://default:597961c4b7344b5f9ce9691ae5fb8bd4@dear-chigger-38419.upstash.io:38419
上記の接続文字列は、Vercel のダッシュボードからコピーした自分のものに置き換えてください。
Redis 設定
読みやすさのため、また記事を流し読みする人のために、設定だけ別のセクションにしました。必要なのは次のとおりです。
const REDIS_CONFIG = {
url: process.env.REDIS_URL,
socket: {
tls: true,
},
};
やり方が分かっている人は、この設定をcreateClient関数に渡すだけで終わりです。tlsは必ずtrueにしてください。ここが抜けていると、接続文字列を正しく書いてもつながりません。本当にこれだけです。
まだ分からない場合は、次のセクションに進んでください。
Redis ボイラープレート
私のボイラープレートを使う必要は特にありませんが、今のプロジェクトではこれを使っています。シングルトンで Redis クライアントを渡すやり方は、無駄がなくていいと思います。設定を組み込んだコードが以下です。自分のプロジェクトでは./redis/index.tsに置いています。
import { createClient, RedisClientType } from "redis";
const REDIS_CONFIG = {
url: process.env.REDIS_URL,
socket: {
tls: true,
},
};
class RedisService {
private static instance: RedisService;
private client: RedisClientType;
private constructor() {
this.client = createClient(REDIS_CONFIG);
this.client.on("error", (err) => console.log("Redis Client Error", err));
this.client.connect();
}
public static getInstance(): RedisService {
if (!RedisService.instance) {
RedisService.instance = new RedisService();
}
return RedisService.instance;
}
getClient() {
return this.client;
}
}
export const getRedisClient = () => RedisService.getInstance().getClient();
上記のコードはgetRedisClient関数をエクスポートしており、これは Vercel KV Redis インスタンスに接続された Redis クライアントを返します。
Redis クライアントの使用
ここを読んでいる人は、実装したい Redis の機能があって来たはずなので、このセクションは要らないかもしれません。ただ、興味本位で読んでいて何か動かしてみたい人もいるでしょう。先ほどエクスポートしたgetRedisClient関数を使って、値を増やす・減らすだけの簡単な例を載せておきます。
import { getRedisClient } from "..";
const COUNTER_NAMESPACE = "counter";
export const incrementCount = async (
increment: number = 1
): Promise<number> => {
const client = getRedisClient();
try {
const newCount = await client.incrBy(`${COUNTER_NAMESPACE}`, increment);
return newCount;
} catch (error) {
console.error(error);
return 0;
}
};
export const decrementCount = async (
decrement: number = 1
): Promise<number> => {
const client = getRedisClient();
try {
const newCount = await client.decrBy(`${COUNTER_NAMESPACE}`, decrement);
if (newCount < 0) {
await client.set(`${COUNTER_NAMESPACE}`, "0");
return 0;
}
return newCount;
} catch (error) {
console.error(error);
return 0;
}
};
export const getCount = async (): Promise<number> => {
const client = getRedisClient();
try {
const count = await client.get(`${COUNTER_NAMESPACE}`);
if (count) {
return parseInt(count);
}
return 0;
} catch (error) {
console.error(error);
return 0;
}
};
動作例
動作する例を GitHub に上げました。こちらからリポジトリを取ってきて、自分で試してみてください。使うときは Vercel KV のインスタンスを作り、接続文字列を取得して、クローンしたリポジトリの.env.localファイルに書く必要があります。忘れないでください。
この記事は元々 dev.to に掲載されています。