Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/entrlcom/go-rate-limit

Limits and Quotas on API Requests with HTTP headers based on IETF draft.
https://github.com/entrlcom/go-rate-limit

api-rate-limit api-rate-limiter go golang ietf ietf-rfcs quota rate-limit rate-limit-redis rate-limiter redis redis-rate-limiter retry-after security token-bucket token-bucket-algorithm

Last synced: 9 days ago
JSON representation

Limits and Quotas on API Requests with HTTP headers based on IETF draft.

Awesome Lists containing this project

README

        

# Rate Limit

## Table of Content

- [Examples](#examples)
- [License](#license)

## Examples

```go
package main

import (
"errors"
"net/http"
"time"

"entrlcom.dev/rate-limit"
"entrlcom.dev/rate-limit/algorithm/token-bucket/redis"
"entrlcom.dev/rate-limit/ietf"
"github.com/redis/rueidis"
)

func main() {
opt, err := rueidis.ParseURL("redis://:[email protected]:6379?protocol=3")
if err != nil {
// TODO: Handle error.
return
}

client, err := rueidis.NewClient(opt)
if err != nil {
// TODO: Handle error.
return
}

quotaPolicy := ietf.NewQuotaPolicy(ietf.NewRequestQuota(250), time.Second)
rateLimit := redis_token_bucket_rate_limit.NewRedisTokenBucketRateLimit(client, quotaPolicy)

handler := NewHandler(&rateLimit)

// ...
}

type Handler struct {
rateLimit rate_limit.RateLimit
}

func (x *Handler) Handle(w http.ResponseWriter, r *http.Request) {
if tokens, err := x.rateLimit.Take(r.Context(), r.RemoteAddr, 5); err != nil {
if errors.Is(err, rate_limit.ErrResourceExhausted) {
headers := x.rateLimit.QuotaPolicy().Headers(time.Now().UTC(), tokens, 5)
if err := headers.Write(w); err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}

http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
return
}

http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}

// ...
}

func NewHandler(rateLimit rate_limit.RateLimit) Handler {
return Handler{rateLimit: rateLimit}
}

```

## License

[MIT](https://choosealicense.com/licenses/mit/)