{"id":76965,"date":"2024-09-17T01:24:53","date_gmt":"2024-09-16T21:54:53","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/"},"modified":"2024-09-17T01:24:53","modified_gmt":"2024-09-16T21:54:53","slug":"4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/","title":{"rendered":"4 \u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc Next.js (2024)"},"content":{"rendered":"<p>Summarize this content to 400 words in Persian Lang \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u062f\u0631 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Next.js\u060c \u0686\u0646\u062f\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u0648\u062b\u0631 \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0627\u0633\u062a. \u0628\u06cc\u0627\u06cc\u06cc\u062f \u06cc\u06a9 \u0645\u0631\u0648\u0631 \u06a9\u0644\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc Next.js \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n<p>  1. \u0646\u0631\u062e \u0627\u06a9\u0633\u067e\u0631\u0633 \u062d\u062f<\/p>\n<p>\u0627\u06cc\u0646 \u0645\u06cc\u0627\u0646\u200c\u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc Express \u0628\u0647\u200c\u0637\u0648\u0631 \u06af\u0633\u062a\u0631\u062f\u0647 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u06cc\u06a9 \u0645\u0634\u062a\u0631\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u062f\u0631 \u06cc\u06a9 \u0628\u0627\u0632\u0647 \u0632\u0645\u0627\u0646\u06cc \u0645\u0639\u06cc\u0646 \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n<p>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc: \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0628\u0627 \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u0646 \u0628\u0633\u062a\u0647 \u0648 \u0627\u0639\u0645\u0627\u0644 \u0622\u0646 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0627\u0632 \u0622\u0646 \u062f\u0631 \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API Next.js \u062e\u0648\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0645\u062b\u0627\u0644:<\/p>\n<p>import rateLimit from &#8216;express-rate-limit&#8217;;<\/p>\n<p>const apiLimiter = rateLimit({<br \/>\n  windowMs: 15 * 60 * 1000, \/\/ 15 minutes<br \/>\n  max: 100, \/\/ limit each IP to 100 requests per windowMs<br \/>\n  message: &#8216;Too many requests, please try again later.&#8217;,<br \/>\n});<\/p>\n<p>export default function handler(req, res) {<br \/>\n  apiLimiter(req, res, () =&gt; {<br \/>\n    res.status(200).json({ data: &#8216;This route is rate-limited.&#8217; });<br \/>\n  });<br \/>\n}<\/p>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f: \u0627\u06cc\u062f\u0647 \u0622\u0644 \u0628\u0631\u0627\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0633\u0627\u062f\u0647 \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0633\u0648\u0621 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0648 \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u0627\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0646\u0635\u0641\u0627\u0646\u0647.<\/p>\n<p>  2. @upstash\/ratelimit<\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0633\u062a\u0647 \u062f\u0631 \u0627\u0633\u0646\u0627\u062f Next.js \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0628\u0647\u200c\u0648\u06cc\u0698\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u062a\u0648\u0627\u0628\u0639 \u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631.<\/p>\n<p>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc: \u0628\u0627 Vercel KV \u0628\u0647 \u062e\u0648\u0628\u06cc \u06a9\u0627\u0631 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0631\u0627 \u062f\u0631 \u06cc\u06a9 \u0645\u062d\u06cc\u0637 Redis \u0645\u0627\u0646\u0646\u062f \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0645\u062b\u0627\u0644:<\/p>\n<p>import { Ratelimit } from &#8216;@upstash\/ratelimit&#8217;;<br \/>\nimport { kv } from &#8216;@vercel\/kv&#8217;;<\/p>\n<p>const rateLimit = new Ratelimit({<br \/>\n  redis: kv,<br \/>\n  limiter: Ratelimit.slidingWindow(5, &#8217;10 s&#8217;), \/\/ 5 requests in 10 seconds<br \/>\n});<\/p>\n<p>export default async function handler(req, res) {<br \/>\n  const { success } = await rateLimit.limit(req.ip);<br \/>\n  if (!success) {<br \/>\n    return res.status(429).json(&#8216;Too many requests&#8217;);<br \/>\n  }<br \/>\n  res.status(200).json({ message: &#8216;Request successful&#8217; });<br \/>\n}<\/p>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f: \u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0632\u06cc\u0646\u0647 \u0628\u0631\u0627\u06cc \u0645\u062d\u06cc\u0637\u200c\u0647\u0627\u06cc \u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631 \u06a9\u0647 \u062f\u0631 \u0622\u0646 \u0628\u0647 \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u06a9\u0627\u0631\u0622\u0645\u062f \u0648 \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u062f.<\/p>\n<p>  3. \u0631\u0627\u0647 \u062d\u0644 \u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Redis<\/p>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Redis \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u0628\u0647 \u062f\u0644\u06cc\u0644 \u0633\u0631\u0639\u062a \u0648 \u06a9\u0627\u0631\u0627\u06cc\u06cc \u0622\u0646 \u062f\u0631 \u0631\u0633\u06cc\u062f\u06af\u06cc \u0628\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0647\u0645\u0632\u0645\u0627\u0646 \u0645\u0624\u062b\u0631 \u0627\u0633\u062a.<\/p>\n<p>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc: \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u0645\u0627\u0646\u0646\u062f ioredis \u0645\u06cc \u062a\u0648\u0627\u0646 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0645\u0646\u0637\u0642 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0633\u0641\u0627\u0631\u0634\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f.<\/p>\n<p>\u0645\u062b\u0627\u0644:<\/p>\n<p>import Redis from &#8216;ioredis&#8217;;<br \/>\nconst redis = new Redis();<\/p>\n<p>const LIMIT = 5; \/\/ requests<br \/>\nconst DURATION = 60; \/\/ seconds<\/p>\n<p>export default async function handler(req, res) {<br \/>\n  const ip = req.headers[&#8216;x-forwarded-for&#8217;] || req.connection.remoteAddress;<br \/>\n  const key = `rate-limit:${ip}`;<\/p>\n<p>  const current = await redis.incr(key);<br \/>\n  if (current === 1) {<br \/>\n    await redis.expire(key, DURATION);<br \/>\n  }<br \/>\n  if (current &gt; LIMIT) {<br \/>\n    return res.status(429).json(&#8216;Too many requests&#8217;);<br \/>\n  }<br \/>\n  res.status(200).json({ message: &#8216;Request successful&#8217; });<br \/>\n}<\/p>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f: \u0645\u0646\u0627\u0633\u0628 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc\u06cc \u0628\u0627 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0628\u0627\u0644\u0627 \u06a9\u0647 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0642\u0648\u06cc \u062f\u0627\u0631\u0646\u062f.<\/p>\n<p>  4. \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 Vercel Edge<\/p>\n<p>Vercel \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0644\u0628\u0647 \u0627\u06cc \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0647 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0631\u0627 \u062f\u0631 \u0644\u0628\u0647 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f\u060c \u06a9\u0647 \u0645\u06cc \u062a\u0648\u0627\u0646\u062f \u0639\u0645\u0644\u06a9\u0631\u062f \u0631\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u062f \u0648 \u062a\u0627\u062e\u06cc\u0631 \u0631\u0627 \u06a9\u0627\u0647\u0634 \u062f\u0647\u062f.<\/p>\n<p>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc: \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 @upstash\/ratelimit \u0628\u0633\u062a\u0647 \u062f\u0631 \u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 Vercel KV \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u06a9\u0627\u0631\u0622\u0645\u062f.<\/p>\n<p>\u0645\u062b\u0627\u0644:<\/p>\n<p>import { NextRequest, NextResponse } from &#8216;next\/server&#8217;;<br \/>\nimport { Ratelimit } from &#8216;@upstash\/ratelimit&#8217;;<br \/>\nimport { kv } from &#8216;@vercel\/kv&#8217;;<\/p>\n<p>const rateLimit = new Ratelimit({<br \/>\n  redis: kv,<br \/>\n  limiter: Ratelimit.slidingWindow(5, &#8217;10 s&#8217;),<br \/>\n});<\/p>\n<p>export default async function middleware(request) {<br \/>\n  const ip = request.ip || &#8216;127.0.0.1&#8217;;<br \/>\n  const { success } = await rateLimit.limit(ip);<br \/>\n  return success ? NextResponse.next() : NextResponse.redirect(&#8216;\/blocked&#8217;);<br \/>\n}<\/p>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f: \u0627\u06cc\u062f\u0647\u200c\u0622\u0644 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0645\u0633\u062a\u0642\u0631 \u062f\u0631 Vercel\u060c \u06a9\u0647 \u0631\u0627\u0647\u06cc \u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u200c\u0647\u0627\u06cc \u0646\u0631\u062e \u062f\u0631 \u0644\u0628\u0647 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n<p>  \u0646\u062a\u06cc\u062c\u0647 \u06af\u06cc\u0631\u06cc<\/p>\n<p>\u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 Next.js \u0634\u0645\u0627 \u0628\u0647 \u0646\u06cc\u0627\u0632\u0647\u0627\u06cc \u062e\u0627\u0635 \u0634\u0645\u0627\u060c \u0645\u0627\u0646\u0646\u062f \u0645\u062d\u06cc\u0637 (\u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631 \u062f\u0631 \u0645\u0642\u0627\u0628\u0644 \u0633\u0631\u0648\u0631 \u0633\u0646\u062a\u06cc)\u060c \u0628\u0627\u0631 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0645\u0648\u0631\u062f \u0627\u0646\u062a\u0638\u0627\u0631\u060c \u0648 \u067e\u06cc\u0686\u06cc\u062f\u06af\u06cc \u0627\u0644\u0632\u0627\u0645\u0627\u062a \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0634\u0645\u0627 \u0628\u0633\u062a\u06af\u06cc \u062f\u0627\u0631\u062f. Express-rate-limit \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0647\u0627\u06cc \u0633\u0627\u062f\u0647 \u0639\u0627\u0644\u06cc \u0627\u0633\u062a\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 @upstash\/ratelimit \u0648 \u0631\u0627\u0647 \u062d\u0644 \u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Redis \u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0642\u0648\u06cc \u062a\u0631\u06cc \u0631\u0627 \u0628\u0631\u0627\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627\u06cc \u067e\u0631\u062a\u0631\u0627\u0641\u06cc\u06a9 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u062f\u0647\u0646\u062f. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vercel Edge Middleware \u0645\u06cc \u062a\u0648\u0627\u0646\u062f \u0639\u0645\u0644\u06a9\u0631\u062f \u0648 \u06a9\u0627\u0631\u0627\u06cc\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u0645\u06cc\u0632\u0628\u0627\u0646\u06cc \u0634\u062f\u0647 \u062f\u0631 Vercel \u0631\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u062f.<\/p>\n<p>\u062f\u0631 \u0646\u0638\u0631\u0627\u062a \u0628\u0647 \u0645\u0646 \u0628\u06af\u0648\u06cc\u06cc\u062f \u0627\u0632 \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u06cc\u062f \u0648 \u0627\u06af\u0631 \u062f\u0631 \u062d\u0627\u0644 \u0633\u0627\u062e\u062a \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Next.js \u0647\u0633\u062a\u06cc\u062f\u060c \u067e\u0631\u0648\u0698\u0647 \u062e\u0648\u062f \u0631\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0628\u06af\u0630\u0627\u0631\u06cc\u062f. \u0645\u0646 \u062f\u0631 \u062d\u0627\u0644 \u0633\u0627\u062e\u062a \u06cc\u06a9 Micro AI SaaS \u0628\u0627 Next.js \u0647\u0633\u062a\u0645. \u0633\u0641\u0631 \u0645\u0646 \u0631\u0627 \u062f\u0646\u0628\u0627\u0644 \u06a9\u0646\u06cc\u062f \u062a\u0627 \u0628\u0628\u06cc\u0646\u06cc\u062f \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0645\u06cc \u0633\u0627\u0632\u0645 \u0648 \u0686\u06af\u0648\u0646\u0647 \u0622\u0646 \u0631\u0627 \u0645\u06cc \u0633\u0627\u0632\u0645.<\/p>\n<p>\u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u062f\u0631 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Next.js\u060c \u0686\u0646\u062f\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u0648\u062b\u0631 \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0627\u0633\u062a. \u0628\u06cc\u0627\u06cc\u06cc\u062f \u06cc\u06a9 \u0645\u0631\u0648\u0631 \u06a9\u0644\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc Next.js \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter-rtl ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u0641\u0647\u0631\u0633\u062a \u0645\u0637\u0627\u0644\u0628<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/#1_%D9%86%D8%B1%D8%AE_%D8%A7%DA%A9%D8%B3%D9%BE%D8%B1%D8%B3_%D8%AD%D8%AF\" >1. \u0646\u0631\u062e \u0627\u06a9\u0633\u067e\u0631\u0633 \u062d\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/#2_upstashratelimit\" >2. @upstash\/ratelimit<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/#3_%D8%B1%D8%A7%D9%87_%D8%AD%D9%84_%D9%87%D8%A7%DB%8C_%D9%85%D8%A8%D8%AA%D9%86%DB%8C_%D8%A8%D8%B1_Redis\" >3. \u0631\u0627\u0647 \u062d\u0644 \u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Redis<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/#4_%D9%85%DB%8C%D8%A7%D9%86_%D8%A7%D9%81%D8%B2%D8%A7%D8%B1_Vercel_Edge\" >4. \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 Vercel Edge<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/nabfollower.com\/blog\/4-best-rate-limiting-solutions-for-nextjs-apps-2024-3ljj\/#%D9%86%D8%AA%DB%8C%D8%AC%D9%87_%DA%AF%DB%8C%D8%B1%DB%8C\" >\u0646\u062a\u06cc\u062c\u0647 \u06af\u06cc\u0631\u06cc<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"1_%D9%86%D8%B1%D8%AE_%D8%A7%DA%A9%D8%B3%D9%BE%D8%B1%D8%B3_%D8%AD%D8%AF\"><\/span>\n<p>  1. <strong>\u0646\u0631\u062e \u0627\u06a9\u0633\u067e\u0631\u0633 \u062d\u062f<\/strong><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u06cc\u0646 \u0645\u06cc\u0627\u0646\u200c\u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc Express \u0628\u0647\u200c\u0637\u0648\u0631 \u06af\u0633\u062a\u0631\u062f\u0647 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u06cc\u06a9 \u0645\u0634\u062a\u0631\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u062f\u0631 \u06cc\u06a9 \u0628\u0627\u0632\u0647 \u0632\u0645\u0627\u0646\u06cc \u0645\u0639\u06cc\u0646 \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n<p><strong>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc<\/strong>: \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0628\u0627 \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u0646 \u0628\u0633\u062a\u0647 \u0648 \u0627\u0639\u0645\u0627\u0644 \u0622\u0646 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0627\u0632 \u0622\u0646 \u062f\u0631 \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API Next.js \u062e\u0648\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p><strong>\u0645\u062b\u0627\u0644<\/strong>:\n<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight jsx\"><code><span class=\"k\">import<\/span> <span class=\"nx\">rateLimit<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">express-rate-limit<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">apiLimiter<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">rateLimit<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">windowMs<\/span><span class=\"p\">:<\/span> <span class=\"mi\">15<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">60<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1000<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ 15 minutes<\/span>\n  <span class=\"na\">max<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ limit each IP to 100 requests per windowMs<\/span>\n  <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">Too many requests, please try again later.<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">handler<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nf\">apiLimiter<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">,<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">status<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nf\">json<\/span><span class=\"p\">({<\/span> <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">This route is rate-limited.<\/span><span class=\"dl\">'<\/span> <span class=\"p\">});<\/span>\n  <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<\/div>\n<p><strong>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f<\/strong>: \u0627\u06cc\u062f\u0647 \u0622\u0644 \u0628\u0631\u0627\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0633\u0627\u062f\u0647 \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0633\u0648\u0621 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0648 \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u0627\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0646\u0635\u0641\u0627\u0646\u0647.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"2_upstashratelimit\"><\/span>\n<p>  2. <strong>@upstash\/ratelimit<\/strong><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u06cc\u0646 \u0628\u0633\u062a\u0647 \u062f\u0631 \u0627\u0633\u0646\u0627\u062f Next.js \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0628\u0647\u200c\u0648\u06cc\u0698\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u062a\u0648\u0627\u0628\u0639 \u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631.<\/p>\n<p><strong>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc<\/strong>: \u0628\u0627 Vercel KV \u0628\u0647 \u062e\u0648\u0628\u06cc \u06a9\u0627\u0631 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0631\u0627 \u062f\u0631 \u06cc\u06a9 \u0645\u062d\u06cc\u0637 Redis \u0645\u0627\u0646\u0646\u062f \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p><strong>\u0645\u062b\u0627\u0644<\/strong>:\n<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight jsx\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Ratelimit<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@upstash\/ratelimit<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">kv<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@vercel\/kv<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">rateLimit<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Ratelimit<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">redis<\/span><span class=\"p\">:<\/span> <span class=\"nx\">kv<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">limiter<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Ratelimit<\/span><span class=\"p\">.<\/span><span class=\"nf\">slidingWindow<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">10 s<\/span><span class=\"dl\">'<\/span><span class=\"p\">),<\/span> <span class=\"c1\">\/\/ 5 requests in 10 seconds<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">handler<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">success<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">rateLimit<\/span><span class=\"p\">.<\/span><span class=\"nf\">limit<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">ip<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">success<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">status<\/span><span class=\"p\">(<\/span><span class=\"mi\">429<\/span><span class=\"p\">).<\/span><span class=\"nf\">json<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Too many requests<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">status<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nf\">json<\/span><span class=\"p\">({<\/span> <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">Request successful<\/span><span class=\"dl\">'<\/span> <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<\/div>\n<p><strong>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f<\/strong>: \u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0632\u06cc\u0646\u0647 \u0628\u0631\u0627\u06cc \u0645\u062d\u06cc\u0637\u200c\u0647\u0627\u06cc \u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631 \u06a9\u0647 \u062f\u0631 \u0622\u0646 \u0628\u0647 \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u06a9\u0627\u0631\u0622\u0645\u062f \u0648 \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u062f.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"3_%D8%B1%D8%A7%D9%87_%D8%AD%D9%84_%D9%87%D8%A7%DB%8C_%D9%85%D8%A8%D8%AA%D9%86%DB%8C_%D8%A8%D8%B1_Redis\"><\/span>\n<p>  3. <strong>\u0631\u0627\u0647 \u062d\u0644 \u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Redis<\/strong><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Redis \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u0628\u0647 \u062f\u0644\u06cc\u0644 \u0633\u0631\u0639\u062a \u0648 \u06a9\u0627\u0631\u0627\u06cc\u06cc \u0622\u0646 \u062f\u0631 \u0631\u0633\u06cc\u062f\u06af\u06cc \u0628\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0647\u0645\u0632\u0645\u0627\u0646 \u0645\u0624\u062b\u0631 \u0627\u0633\u062a.<\/p>\n<p><strong>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc<\/strong>: \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u0645\u0627\u0646\u0646\u062f <code>ioredis<\/code> \u0645\u06cc \u062a\u0648\u0627\u0646 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0645\u0646\u0637\u0642 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0633\u0641\u0627\u0631\u0634\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f.<\/p>\n<p><strong>\u0645\u062b\u0627\u0644<\/strong>:\n<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight jsx\"><code><span class=\"k\">import<\/span> <span class=\"nx\">Redis<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">ioredis<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">redis<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Redis<\/span><span class=\"p\">();<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">LIMIT<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">5<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ requests<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">DURATION<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">60<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ seconds<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">handler<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">ip<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">x-forwarded-for<\/span><span class=\"dl\">'<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">connection<\/span><span class=\"p\">.<\/span><span class=\"nx\">remoteAddress<\/span><span class=\"p\">;<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">key<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">`rate-limit:<\/span><span class=\"p\">${<\/span><span class=\"nx\">ip<\/span><span class=\"p\">}<\/span><span class=\"s2\">`<\/span><span class=\"p\">;<\/span>\n\n  <span class=\"kd\">const<\/span> <span class=\"nx\">current<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">redis<\/span><span class=\"p\">.<\/span><span class=\"nf\">incr<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">current<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">await<\/span> <span class=\"nx\">redis<\/span><span class=\"p\">.<\/span><span class=\"nf\">expire<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">DURATION<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">current<\/span> <span class=\"o\">&gt;<\/span> <span class=\"nx\">LIMIT<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">status<\/span><span class=\"p\">(<\/span><span class=\"mi\">429<\/span><span class=\"p\">).<\/span><span class=\"nf\">json<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Too many requests<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">status<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nf\">json<\/span><span class=\"p\">({<\/span> <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">Request successful<\/span><span class=\"dl\">'<\/span> <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<\/div>\n<p><strong>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f<\/strong>: \u0645\u0646\u0627\u0633\u0628 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc\u06cc \u0628\u0627 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0628\u0627\u0644\u0627 \u06a9\u0647 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0642\u0648\u06cc \u062f\u0627\u0631\u0646\u062f.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"4_%D9%85%DB%8C%D8%A7%D9%86_%D8%A7%D9%81%D8%B2%D8%A7%D8%B1_Vercel_Edge\"><\/span>\n<p>  4. <strong>\u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 Vercel Edge<\/strong><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Vercel \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0644\u0628\u0647 \u0627\u06cc \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0647 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u0631\u0627 \u062f\u0631 \u0644\u0628\u0647 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f\u060c \u06a9\u0647 \u0645\u06cc \u062a\u0648\u0627\u0646\u062f \u0639\u0645\u0644\u06a9\u0631\u062f \u0631\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u062f \u0648 \u062a\u0627\u062e\u06cc\u0631 \u0631\u0627 \u06a9\u0627\u0647\u0634 \u062f\u0647\u062f.<\/p>\n<p><strong>\u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc<\/strong>: \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 <code>@upstash\/ratelimit<\/code> \u0628\u0633\u062a\u0647 \u062f\u0631 \u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 Vercel KV \u0628\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0646\u0631\u062e \u06a9\u0627\u0631\u0622\u0645\u062f.<\/p>\n<p><strong>\u0645\u062b\u0627\u0644<\/strong>:\n<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight jsx\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">NextRequest<\/span><span class=\"p\">,<\/span> <span class=\"nx\">NextResponse<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">next\/server<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Ratelimit<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@upstash\/ratelimit<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">kv<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@vercel\/kv<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">rateLimit<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Ratelimit<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">redis<\/span><span class=\"p\">:<\/span> <span class=\"nx\">kv<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">limiter<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Ratelimit<\/span><span class=\"p\">.<\/span><span class=\"nf\">slidingWindow<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">10 s<\/span><span class=\"dl\">'<\/span><span class=\"p\">),<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">middleware<\/span><span class=\"p\">(<\/span><span class=\"nx\">request<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">ip<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">request<\/span><span class=\"p\">.<\/span><span class=\"nx\">ip<\/span> <span class=\"o\">||<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">127.0.0.1<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">success<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">rateLimit<\/span><span class=\"p\">.<\/span><span class=\"nf\">limit<\/span><span class=\"p\">(<\/span><span class=\"nx\">ip<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">success<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">NextResponse<\/span><span class=\"p\">.<\/span><span class=\"nf\">next<\/span><span class=\"p\">()<\/span> <span class=\"p\">:<\/span> <span class=\"nx\">NextResponse<\/span><span class=\"p\">.<\/span><span class=\"nf\">redirect<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">\/blocked<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<\/code><\/pre>\n<\/div>\n<p><strong>\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0645\u0648\u0631\u062f<\/strong>: \u0627\u06cc\u062f\u0647\u200c\u0622\u0644 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0645\u0633\u062a\u0642\u0631 \u062f\u0631 Vercel\u060c \u06a9\u0647 \u0631\u0627\u0647\u06cc \u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u200c\u0647\u0627\u06cc \u0646\u0631\u062e \u062f\u0631 \u0644\u0628\u0647 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"%D9%86%D8%AA%DB%8C%D8%AC%D9%87_%DA%AF%DB%8C%D8%B1%DB%8C\"><\/span>\n<p>  \u0646\u062a\u06cc\u062c\u0647 \u06af\u06cc\u0631\u06cc<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 Next.js \u0634\u0645\u0627 \u0628\u0647 \u0646\u06cc\u0627\u0632\u0647\u0627\u06cc \u062e\u0627\u0635 \u0634\u0645\u0627\u060c \u0645\u0627\u0646\u0646\u062f \u0645\u062d\u06cc\u0637 (\u0628\u062f\u0648\u0646 \u0633\u0631\u0648\u0631 \u062f\u0631 \u0645\u0642\u0627\u0628\u0644 \u0633\u0631\u0648\u0631 \u0633\u0646\u062a\u06cc)\u060c \u0628\u0627\u0631 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0645\u0648\u0631\u062f \u0627\u0646\u062a\u0638\u0627\u0631\u060c \u0648 \u067e\u06cc\u0686\u06cc\u062f\u06af\u06cc \u0627\u0644\u0632\u0627\u0645\u0627\u062a \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0634\u0645\u0627 \u0628\u0633\u062a\u06af\u06cc \u062f\u0627\u0631\u062f. Express-rate-limit \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0647\u0627\u06cc \u0633\u0627\u062f\u0647 \u0639\u0627\u0644\u06cc \u0627\u0633\u062a\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 @upstash\/ratelimit \u0648 \u0631\u0627\u0647 \u062d\u0644 \u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Redis \u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0642\u0648\u06cc \u062a\u0631\u06cc \u0631\u0627 \u0628\u0631\u0627\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627\u06cc \u067e\u0631\u062a\u0631\u0627\u0641\u06cc\u06a9 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u062f\u0647\u0646\u062f. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vercel Edge Middleware \u0645\u06cc \u062a\u0648\u0627\u0646\u062f \u0639\u0645\u0644\u06a9\u0631\u062f \u0648 \u06a9\u0627\u0631\u0627\u06cc\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u0645\u06cc\u0632\u0628\u0627\u0646\u06cc \u0634\u062f\u0647 \u062f\u0631 Vercel \u0631\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u062f.<\/p>\n<p>\u062f\u0631 \u0646\u0638\u0631\u0627\u062a \u0628\u0647 \u0645\u0646 \u0628\u06af\u0648\u06cc\u06cc\u062f \u0627\u0632 \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u06cc\u062f \u0648 \u0627\u06af\u0631 \u062f\u0631 \u062d\u0627\u0644 \u0633\u0627\u062e\u062a \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Next.js \u0647\u0633\u062a\u06cc\u062f\u060c \u067e\u0631\u0648\u0698\u0647 \u062e\u0648\u062f \u0631\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0628\u06af\u0630\u0627\u0631\u06cc\u062f. \u0645\u0646 \u062f\u0631 \u062d\u0627\u0644 \u0633\u0627\u062e\u062a \u06cc\u06a9 Micro AI SaaS \u0628\u0627 Next.js \u0647\u0633\u062a\u0645. \u0633\u0641\u0631 \u0645\u0646 \u0631\u0627 \u062f\u0646\u0628\u0627\u0644 \u06a9\u0646\u06cc\u062f \u062a\u0627 \u0628\u0628\u06cc\u0646\u06cc\u062f \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0645\u06cc \u0633\u0627\u0632\u0645 \u0648 \u0686\u06af\u0648\u0646\u0647 \u0622\u0646 \u0631\u0627 \u0645\u06cc \u0633\u0627\u0632\u0645.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summarize this content to 400 words in Persian Lang \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e \u062f\u0631 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Next.js\u060c \u0686\u0646\u062f\u06cc\u0646 \u0631\u0627\u0647 \u062d\u0644 \u0645\u0648\u062b\u0631 \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0627\u0633\u062a. \u0628\u06cc\u0627\u06cc\u06cc\u062f \u06cc\u06a9 \u0645\u0631\u0648\u0631 \u06a9\u0644\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u0646\u062f\u0647 \u0646\u0631\u062e \u0628\u0631\u0627\u06cc Next.js \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645: 1. \u0646\u0631\u062e \u0627\u06a9\u0633\u067e\u0631\u0633 \u062d\u062f \u0627\u06cc\u0646 \u0645\u06cc\u0627\u0646\u200c\u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc Express \u0628\u0647\u200c\u0637\u0648\u0631 \u06af\u0633\u062a\u0631\u062f\u0647 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 &hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-76965","post","type-post","status-publish","format-standard","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/76965","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=76965"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/76965\/revisions"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=76965"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=76965"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=76965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}