httprate
net/http request rate limiter based on the Sliding Window Counter pattern inspired by
CloudFlare https://blog.cloudflare.com/counting-things-a-lot-of-different-things/.
The sliding window counter pattern is accurate, smooths traffic and offers a simple counter
design to share a rate-limit among a cluster of servers. For example, if you'd like
to use redis to coordinate a rate-limit across a group of microservices you just need
to implement the httprate.LimitCounter interface to support an atomic increment
and get.
Example
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httprate"
)
func main() {
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(httprate.LimitByIP(100, 1*time.Minute))
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("."))
})
http.ListenAndServe(":3333", r)
}
Common use cases
Rate limit by IP and URL path (aka endpoint)
r.Use(httprate.Limit(
10,
10*time.Second,
httprate.WithKeyFuncs(httprate.KeyByIP, httprate.KeyByEndpoint),
))
Rate limit by arbitrary keys
r.Use(httprate.Limit(
100,
1*time.Minute,
httprate.WithKeyFuncs(func(r *http.Request) (string, error) {
return r.Header.Get("X-Access-Token"), nil
}),
))
Send specific response for rate limited requests
r.Use(httprate.Limit(
10,
1*time.Second,
httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "some specific response here", http.StatusTooManyRequests)
}),
))
Related packages
Redis backend for httprate: https://github.com/go-chi/httprate-redis
LICENSE
MIT