Skip to content

Instantly share code, notes, and snippets.

@thiagozs
Created November 28, 2023 15:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thiagozs/188f88783867e23178392a5772ce2b6c to your computer and use it in GitHub Desktop.
Save thiagozs/188f88783867e23178392a5772ce2b6c to your computer and use it in GitHub Desktop.
Poc Redis Rate Limit middleware
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/go-redis/redis/v8"
"github.com/labstack/echo/v4"
)
func RedisRateLimiterMiddleware(client *redis.Client, limit int, resetTime time.Duration) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Identify the user, IP, or some unique client identifier
identifier := c.Request().RemoteAddr
key := fmt.Sprintf("ratelimit:%s", identifier)
ctx := context.Background()
// Increment the count in Redis
count, err := client.Get(ctx, key).Int()
if err == redis.Nil {
// Key does not exist, so create it with an expiry
client.Set(ctx, key, 1, resetTime)
} else if err != nil {
// Handle error
return echo.NewHTTPError(http.StatusInternalServerError, "Redis error")
} else if count >= limit {
// Rate limit exceeded
return echo.NewHTTPError(http.StatusTooManyRequests, "Too many requests")
} else {
// Increment the count
client.Incr(ctx, key)
}
return next(c)
}
}
}
func main() {
e := echo.New()
// Initialize Redis client
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // or your Redis server address
Password: "", // no password set
DB: 0, // use default DB
})
e.Use(RedisRateLimiterMiddleware(redisClient, 10, 1*time.Hour))
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Start(":8080")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment