Next.jsでのRate Limitingの実装
はじめに
アプリケーションにおいて、Rate Limitingはとても重要な機能です。
Next.jsでの実装はとても簡単なので、本記事ではUpstashというサービスを使用して、Next.jsでのRate Limitingの実装方法を紹介します。
技術スタック
- Next.js
- Upstash
- Redis
- tRPC
Upstashとは
Upstashは、Redisをサーバーレスで提供するサービスです。
とても手軽にRedisを使用することができ、無料枠もあるのでおすすめです。
1. 環境変数の設定
まずUpstashのアカウントを作成し、Redisのデータベースを作成します。
続いて、データベースの接続情報を環境変数に設定します。
図のように、REST API
の項目にて、.env
の内容をコピーしして自分のプロジェクトの.env
に貼り付けます。
2. Rate Limitingの実装
まずUpstashのライブラリーをインストールします。
bun install @upstash/ratelimit @upstash/redis
続いて、サンプルコードのように、Ratelimit
とRedis
をインポートし、Ratelimit
を初期化します。
この設定では、60秒間に1回のリクエストを許可するように設定しています。
import {postRouter} from "~/server/api/routers/post";
import {createTRPCRouter} from "~/server/api/trpc";
+ import {Ratelimit} from "@upstash/ratelimit";
+ import {Redis} from "@upstash/redis";
/**
* This is the primary router for your server.
*
* All routers added in /api/routers should be manually added here.
*/
export const appRouter = createTRPCRouter({
post: postRouter,
});
+ export const rateLimiter = new Ratelimit({
+ redis: Redis.fromEnv(),
+ limiter: Ratelimit.slidingWindow(1, "60 s")
+ });
// export type definition of API
export type AppRouter = typeof appRouter;
続いて、サンプルコードのようにRate Limitingを実装したいAPIの関数にて、rateLimiter
を使用します。
このAPIは、ユーザーIDごとに60秒間に1回のリクエストを許可するように設定しています。
リクエストが多すぎる場合は、TOO_MANY_REQUESTS
のエラーを返します。
import {rateLimiter} from "~/server/api/root";
import {TRPCError} from "@trpc/server";
export const postRouter = createTRPCRouter({
// ...省略
create: protectedProcedure
.input(z.object({name: z.string().min(1)}))
.mutation(async ({ctx, input}) => {
+ const {success} = await rateLimiter.limit(ctx.session.user.id);
+ if (!success) {
+ throw new TRPCError({code: "TOO_MANY_REQUESTS"});
+ }
// simulate a slow db call
await new Promise((resolve) => setTimeout(resolve, 1000));
await ctx.db.insert(posts).values({
name: input.name,
createdById: ctx.session.user.id,
});
}),
// ...省略
3. 動作確認
続いて、実際に動作確認を行います。
アプリを起動後にログインし、適当に投稿を作成します。
その後、60秒以内に再度投稿を作成しようとすると、TOO_MANY_REQUESTS
のエラーが発生することが確認できます。
まとめ
Next.jsでのRate Limitingの実装はとても簡単でした。
Upstashを使用することで、Redisの管理も簡単に行うことができます。
ぜひ、Next.jsでのRate Limitingの実装にUpstashをお試しください。
Discussion