Skip to content

Should it be more convenient to use multiple Rates at the same time? #32

@Hubro

Description

@Hubro

I want to rate limit my API's login endpoint thusly: max 1 request per second, max 5 requests per hour, max 10 requests per day.

I have implemented it like this using your middleware:

func loginLimiterHandler() http.Handler {
	secondRate := limiter.Rate{Period: 1 * time.Second, Limit: 1}
	hourRate := limiter.Rate{Period: 1 * time.Hour, Limit: 5}
	dayRate := limiter.Rate{Period: 24 * time.Hour, Limit: 10}

	secondLimit := limiter.New(memory.NewStore(), secondRate)
	hourLimit := limiter.New(memory.NewStore(), hourRate)
	dayLimit := limiter.New(memory.NewStore(), dayRate)

	var handler http.Handler = http.HandlerFunc(LoginHandler)

	handler = stdlib.NewMiddleware(dayLimit).Handler(handler)
	handler = stdlib.NewMiddleware(hourLimit).Handler(handler)
	handler = stdlib.NewMiddleware(secondLimit).Handler(handler)

	return handler
}

I think it would be practical to add the function limiter.NewMultipleRates (or similar) to allow this:

func loginLimiterHandler() http.Handler {
	secondRate := limiter.Rate{Period: 1 * time.Second, Limit: 1}
	hourRate := limiter.Rate{Period: 1 * time.Hour, Limit: 5}
	dayRate := limiter.Rate{Period: 24 * time.Hour, Limit: 10}

	limit := limiter.NewMultipleRates(memory.NewStore(), secondRate, hourRate, dayRate)

	return stdlib.NewMiddleware(limit).Handler(http.HandlerFunc(LoginHandler))
}

That way you could also properly display all the right HTTP headers. With my solution, when the second-limit blocks the request, the response doesn't include headers about the hourly or daily limits.

My apologies in advance if I've massively over-complicated my solution.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions