Home
Published

Integrate @upstash/ratelimit into Astro

This article shows how to add @upstash/ratelimit to Astro's middleware to control access to endpoints.
avatar
Boluo
Table of Contents

Prerequisites

Code

import { Redis } from '@upstash/redis'
import { Ratelimit } from '@upstash/ratelimit'

const redis = Redis.fromEnv();

export const ratelimit = {
  ip: new Ratelimit({
    redis,
    limiter: Ratelimit.slidingWindow(10, '30 s'),
    ephemeralCache: new Map(),
    analytics: true
  })
}

export const checkIpRateLimit = async (ip: string) => {
  const key = `ip:${ip}`
  const { success } = await ratelimit.ip.limit(key)
  return success
}
import { defineMiddleware } from "astro:middleware"

export const onRequest = defineMiddleware(async (context, next) => {
  const { request } = context
  const pathname = new URL(request.url).pathname

  if (pathname.startsWith("/api")) {
    const { clientAddress } = context
    const { checkIpRateLimit } = await import("~lib/redis")
    const success = await checkIpRateLimit(clientAddress)

    if (!success) {
      return new Response(
        JSON.stringify({
          error: "Rate limit exceeded"
        }),
        { status: 429 }
      )
    }
  }

  return next()
})

Enviroments

To use the ratelimit feature, we must set the UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN environment variables.

Conclusions

If you spot any mistakes in the article, or if you have any questions, don’t hesitate to drop me a message on Twitter.

I’m working on polishing my English writing. I’d be thankful if you could spot any parts that don’t quite match a native speaker’s touch. Just like this sentence.

Let’s stay connected.

Share this article instantly on
Last Modified:
Licensed under CC BY-NC-SA 4.0