DEV Community

Cover image for Implementing Rate Limiting in a Spring Boot API using Bucket4j
Tharindu Dulshan Fernando
Tharindu Dulshan Fernando

Posted on

Implementing Rate Limiting in a Spring Boot API using Bucket4j

In this blog, we’ll explore how to add rate limiting to a Spring Boot API using Bucket4j. Applying Rate limiting will help control the number of requests a client can make to your API within a certain period to protect server resources and ensure fair usage.

Introduction for Bucket4j

Bucket4j is a Java rate-limiting library that is used to implement various algorithms like token buckets and leaky buckets for rate limiting. It is highly efficient and easy to integrate with any Java-based application, including Spring Boot.

Let’s set up a Spring Boot Project

Create a spring boot app and add the below dependencies.

<!-- Bucket4j -->
<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>3.1.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Creating a Rate Limiting Service

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;

import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RateLimitingService {

    private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();

    public boolean allowRequest(String apiKey) {
        Bucket bucket = buckets.computeIfAbsent(apiKey, this::createNewBucket);
        return bucket.tryConsume(1);
    }

    private Bucket createNewBucket(String apiKey) {
        Bandwidth limit = Bandwidth.classic(10, Refill.intervally(10, Duration.ofMinutes(1)));
        return Bucket4j.builder().addLimit(limit).build();
    }
}
Enter fullscreen mode Exit fullscreen mode

**Note: If Refill.intervally is not available you can use Refill.smooth

In this RateLimitingService class:

  • We use a ConcurrentHashMap to store a bucket for each API key.

  • The allowRequest method checks if a request can be consumed from the bucket associated with the given API key.

  • The createNewBucket method creates a new bucket with a rate limit of 10 requests per minute.

Now let’s create a RateLimitingController class to integrate ratelimiting on API.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/rate-limiting")
public class RateLimitingController {

    private final RateLimitingService rateLimitingService;

    public RateLimitingController(RateLimitingService rateLimitingService) {
        this.rateLimitingService = rateLimitingService;
    }

    @GetMapping("/resource")
    public String getResource() {
        String apiKey = "test-api-key"; // Retrieve API key from request headers or JWT token
        if (rateLimitingService.allowRequest(apiKey)) {
            return "Resource api accessed successfully";
        } else {
            return "Rate limit exceeded. Please Try again later.";
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In this RateLimitingController class:

  • We inject the RateLimitingService into the controller.

  • The getResource method checks if the request can be allowed based on the rate limit associated with the API key.

Conclusion

In this tutorial, it’s shown how to use Bucket4j to build rate restrictions in a Spring Boot API. You can protect your APIs against misuse and guarantee equitable client usage by managing the volume of incoming requests. Token buckets and other algorithm-based rate constraints can be effectively and adaptably implemented using Bucket4j. You are welcome to alter the rate-limiting parameters to suit the needs of your particular application.

For more advanced scenarios, consider integrating Bucket4j with caching mechanisms like Redis for distributed rate limiting across multiple server instances.

References

https://bucket4j.com/
https://github.com/bucket4j/bucket4j
https://github.com/bucket4j/bucket4j

Code Reference

https://github.com/tharindu1998/rate-limiting-example

Top comments (0)