https://github.com/robotomize/go-ratelimiter
A super easy rate limiting package for Go
https://github.com/robotomize/go-ratelimiter
go golang rate-limiter rate-limiting redis
Last synced: about 2 months ago
JSON representation
A super easy rate limiting package for Go
- Host: GitHub
- URL: https://github.com/robotomize/go-ratelimiter
- Owner: robotomize
- License: apache-2.0
- Created: 2022-04-01T14:16:08.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2024-12-19T13:50:15.000Z (5 months ago)
- Last Synced: 2025-02-08T14:15:58.928Z (4 months ago)
- Topics: go, golang, rate-limiter, rate-limiting, redis
- Language: Go
- Homepage:
- Size: 54.7 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# go-ratelimiter
[](https://goreportcard.com/report/github.com/robotomize/gokuu)
[](https://codebeat.co/projects/github-com-robotomize-go-ratelimiter-main)
[](https://codecov.io/gh/robotomize/go-ratelimiter)
[](https://github.com/robotomize/go-ratelimiter/actions)
[](https://github.com/robotomize/go-ratelimiter/blob/master/LICENSE)A super easy rate limiting package for Go. Package provide Store interface, for which you can use your own
implementations# Install
```shell
go get github.com/robotomize/go-ratelimiter
```# Usage
Example of using redis datastore
```go
package main
import (
"context"
"fmt"
"log"
"time""github.com/robotomize/go-ratelimiter"
)func main() {
// set a limit of 10 request per 1 seconds per api key
redisStore, err := ratelimiter.DefaultRedisStore(context.Background(), ":6379", 1*time.Second, 10)
if err != nil {
log.Fatal(err)
}// Retrieve data by the api key in the datastore
limit, remaining, resetTime, ok, err := redisStore.Take(context.Background(), "apikey-1")
if err != nil {
log.Fatal(err)
}if !ok {
fmt.Println("limit exceeded")
}// Print the constraints from the datastore
fmt.Printf(
"resource: maximum %d, remaining %d, reset time %s",
limit, remaining, time.Unix(0, int64(resetTime)).UTC().Format(time.RFC1123),
)
}```
To limit access at the http level, you can use middleware, which can block the request by providing the http code 429
Too Many RequestsExample of using http middleware with redis datastore
```go
package mainimport (
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"time""github.com/robotomize/go-ratelimiter"
)func main() {
// set a limit of 5 request per 1 seconds per api key
redisStore, err := ratelimiter.DefaultRedisStore(context.Background(), ":6379", 1*time.Second, 5)
if err != nil {
log.Fatal(err)
}mx := http.NewServeMux()
// Let's create a test handler
healthHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status": "ok"}`))
})
mx.Handle(
"/health", ratelimiter.LimiterMiddleware(
redisStore, func(r *http.Request) (string, error) {
// Example key func
ctx := r.Context()
// Get key value out of context
ctxValue := ctx.Value("apikey")
if key, ok := ctxValue.(string); ok {
return key, nil
}return "", errors.New("get api key from ctx")
}, ratelimiter.WithSkipper(func() bool {
// set a skipper, skip ratelimiter if DEBUG == 1
return os.Getenv("DEBUG") == "1"
}, ),
)(healthHandler),
)// start listener
if err = http.ListenAndServe(":8888", mx); err != nil {
log.Fatal(err)
}
}
```# TODO
* ~add http middleware~
* ~add redis datastore~
* improve unit coverage
* improve redis datastore
* add tarantool datastore
* add aerospike datastore## Contributing
## License
go-ratelimiter is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.