Michael Charles Aubrey

https://MichaelCharl.es/Aubrey

Node 'redis'ライブラリを使用してVercel KVに接続する方法

Node 'redis'ライブラリを使用してVercel KVに接続する方法

Michael Charles Aubrey // Mon Nov 13 2023

Vercel KV(Key-Value)は Vercel の新しいサービスで、サーバーレスのキーバリューストアを手軽に使えます。Upstash の Redis 機能を利用して Redis の上に作られており、これを操作するための Node ライブラリ @vercel/kv も Vercel が出しています。NextJS のサーバーレスエッジ関数の中でキーバリューストレージを使うなら、@vercel/kvがちょうどいいでしょう。

なぜ @vercel/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 に掲載されています。

Michael Charles Aubrey

Developer at Maki
Based in Akita, Japan

Connect

© 2026 Michael Charles Aubrey. All rights reserved.

Born in Florida 🏝️ • Lives in Akita 👹