While working on my CypherGoat project ,when exposing the API, I needed to setup some rate limiting to avoid getting spammed. Since my API uses Gin as its HTTP library, I used for the limiter
package to handle the rate limiting.
Setting up the rate limiting
In my implementation I am setting a 30 request/minute limit on each IP interacting with my API.
Here is some example code:
package main
import (
"time"
"github.com/gin-gonic/gin"
"github.com/ulule/limiter/v3"
ginlimiter "github.com/ulule/limiter/v3/drivers/middleware/gin"
memory "github.com/ulule/limiter/v3/drivers/store/memory"
)
func main() {
router := gin.Default()
rate := limiter.Rate{
Period: 1 * time.Minute,
Limit: 30, // 30 Requests/minute limit
}
store := memory.NewStore()
// Create the rate limiter
instance := limiter.New(store, rate)
// Middleware to apply rate limiting per IP
router.Use(ginlimiter.NewMiddleware(instance))
// Example endpoint
router.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Hello World!"})
})
// Start server
router.Run(":8080")
}
We first create a new gin router called router.
After that we setup a rate limiting policy. In this case it is 30 Requests/minute
After that we create an in memory store to store all of the IP’s and their request counts.
Then we create a new rate limiting instance and use it using router.Use
After that we define a standard example route to “/” that returns Hello World and run it on port 8080
You can test this by going to your web browser to localhost:8080/
and send 30 requests (30 refreshes) in one minute and you should see Limit exceeded
That’s about it.
Join my free newsletter
Related Articles
Deploying Go + Templ + HTMX + TailwindCSS to production