go-ratelimiter
This is a negroni middleware that offers request rate limiting using token bucket approach.
It can apply a global rate limit or per key (where you can specify how to obtain the key from the request).
Additionally you can apply a different rate limit per key.
Getting Started
Global rate limiting
To add a global rate limit across all your request with a rate of 1 request per second.
m := NewGlobal().
WithDefaultQuota(1, time.Second).
Middleware()
n := negroni.Classic(m)
ts := httptest.NewServer(n)
defer ts.Close()
Changing status code
By default the status code 429 Too Many Requests
will be returned when the specified rate limit is exceeded. In you want to change this behavior and return a different status code, just do:
m := NewGlobal().
WithDefaultQuota(1, time.Second).
WithStatusCode(400).
Middleware()
In this case instead of the 429
, a 400 Bad Request
will be returned.
Rate limiting for different kind of request
Sometimes you want to apply a different rate for different kind of request. Lets take as an example that an account_id is being passed as a query parameter, and we want to apply the limit of 1 request per second
but for each account individually instead of globally. In this case you can achieve it by doing:
getKey := func(req *http.Request) string {
return req.URL.Query().Get("account_id")
}
m := NewLimitByKeys(getKey).
WithDefaultQuota(1, time.Second).
Middleware()
...
Different rate limits for different requests
Using the same example as previously, you can additionally specify a different rate limit for different accounts.
getKey := func(req *http.Request) string {
return req.URL.Query().Get("account_id")
}
getQuota := func(key string) Quota {
if key == "2" {
return NewQuota(1, time.Minute)
}
return NewQuota(2, time.Second)
}
m := NewLimitByKeys(getKey).
WithQuotaByKeys(getQuota).
Middleware()
...
This middleware will return the following headers:
X-RateLimit-Limit
With the set request limit in RPM (taking in account if you specified a key and different quotas per key)
Retry-After
With the time in seconds the client should wait until he can issue another request. This is only sent if the limit has been reached