Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

Upstash RedisでNext.js APIルートにレート制限を実装する方法

この記事では、Upstash Rate Limit SDKを使用して、Next.jsのAPIルートにレート制限(レートリミット)を実装する手順を解説します。

データベースのセットアップ

まず、Upstash ConsoleまたはUpstash CLIを使ってRedisデータベースを作成します。作成後、次の手順で必要になるUPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENを控えておきましょう。

プロジェクトのセットアップ

Next.jsアプリケーションを作成し、Vercelにデプロイします。

npx create-next-app@latest

続いて、@upstash/ratelimitをインストールします。

npm install @upstash/ratelimit @upstash/redis

コードの実装

pages/api/hello.jsを以下のように書き換え、UPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENを実際の値に置き換えてください。

pages/api/hello.js

import {Ratelimit} from "@upstash/ratelimit";
import {Redis} from "@upstash/redis";

const redis = new Redis({
  url: 'UPSTASH_REDIS_REST_URL',
  token: 'UPSTASH_REDIS_REST_TOKEN',
})

// 5秒あたり5リクエストまで許可するレートリミッターを作成
const ratelimit = new Ratelimit({
  redis: redis,
  limiter: Ratelimit.fixedWindow(5, "5 s"),
});

export default async function handler(req, res) {
  // 定数文字列を使えば全リクエストに対して単一のレート制限を適用できる
  // ユーザーIDやAPIキー、IPアドレスを使えば個別の制限も可能
  const identifier = "api";
  const result = await ratelimit.limit(identifier);
  res.setHeader('X-RateLimit-Limit', result.limit)
  res.setHeader('X-RateLimit-Remaining', result.remaining)

  if (!result.success) {
    res.status(200).json({message: 'レート制限によりリクエストが拒否されました。', rateLimitState: result})
    return
  }

  res.status(200).json({name: 'John Doe', rateLimitState: result})
}

このコードでは、「5秒間に5リクエスト」という制限を設定しています。

動作確認

npm run devでアプリケーションを起動し、ブラウザを6回以上更新してみてください。レート制限が機能している様子を確認できます。

{"message":"The request has been rate limited.","rateLimitState":{"success":false,"limit":5,"remaining":-1,"reset":1654546770000,"pending":{}}}

さらなる改善ポイント

  • ユーザーごとの制限: ユーザーIDやIPアドレスを識別子として使えば、ユーザー単位での利用制限が可能です。
   const identifier = getClientIp(req);
   const result = await ratelimit.limit(identifier);
  • スライディングウィンドウアルゴリズム: より滑らかなレート制御を実現できます(その分コストは高くなります)。
 const ratelimit = new Ratelimit({
  redis: redis,
  limiter: Ratelimit.slidingWindow(10, "10 s"),
});
  • トークンバケットアルゴリズム: 一定量のトラフィックスパイクを許容したい場合に有効です。
 const ratelimit = new Ratelimit({
  redis: redis,
  limiter: Ratelimit.tokenBucket(5, "10 s", 10),
});
  • マルチリージョン構成: Next.jsアプリケーションを複数リージョンにデプロイしている場合は、各リージョンにRedisを配置することで、各地からのアクセス遅延を最小化できます。
  • 認証情報の安全管理: Upstash Redisのクレデンシャルは環境変数やシークレットストアで管理し、コードに直接記述しないようにしましょう。
  1. RenderとUpstashでNext.jsアプリをサーバーレスRedisと共にデプロイする方法

    Renderは、即時デプロイやオートスケーリングなどの機能を備えた強力なインフラストラクチャプラットフォームです。この記事では、Upstashを使ってシンプルなNext.jsアプリケーションを作成し、それをRenderにデプロイする手順を解説します。 注意:このチュートリアルでは、UpstashでRedisインスタンスがすでに作成済みであることを前提としています。まだ作成していない場合は、Upstashコンソールから簡単に作成できます。 はじめに まず、新しいNext.jsアプリを作成し、そのディレクトリに移動しましょう。 npx create-next-app upstash-render

  2. UpstashのPipeline APIでサーバーレスRedisを高速化:複数コマンドを1リクエストで実行

    Upstashは、ネイティブなRedis APIに加えてREST APIもサポートしており、開発者はサーバーレス関数やエッジ関数から接続の問題を気にせずRedisへアクセスできます。しかし、同じ関数内で複数のRedisコマンドを実行する場合、その回数だけデータベースへの呼び出しが発生してしまうという課題がありました。 そこで、コミュニティメンバーの一人である@MasterGates氏が、Discordチャンネルで素晴らしい提案をしてくれました。それが「Pipeline API」です。 Pipeline APIとは Pipeline APIは、RedisのPIPELINEコマンドをREST A