Problem
The project currently lacks protection against API abuse and excessive request rates. This leads to:
- Vulnerability to brute-force attacks and DoS attempts
- Potential resource exhaustion from malicious or misconfigured clients
- Unfair resource allocation when multiple clients access the API
- No throttling mechanism to protect backend services and database
- Difficulty managing costs and capacity planning
- Poor quality of service for legitimate users during traffic spikes
Without rate limiting, the API is exposed to abuse scenarios that can degrade performance, increase infrastructure costs, and compromise system availability.
Proposed Solution
Integrate Bucket4j as the rate-limiting library for the Spring Boot RESTful API. This will:
- Provide robust, in-memory rate limiting based on the token bucket algorithm
- Protect endpoints from excessive requests and abuse patterns
- Ensure fair resource allocation across API consumers
- Return standard HTTP 429 (Too Many Requests) responses when limits are exceeded
- Improve overall system reliability and user experience
- Enable fine-grained control over request rates per endpoint or client
- Integrate seamlessly with Spring Boot's filter/interceptor architecture
Suggested Approach
-
Add Bucket4j dependency
<dependency>
<groupId>com.bucket4j</groupId>
<artifactId>bucket4j-core</artifactId>
<version>8.17.0</version>
</dependency>
-
Create rate limit configuration class
- Create
src/main/java/.../config/RateLimitConfig.java:
- Define rate limit rules (e.g., 10 requests per minute, 100 per hour)
- Configure bucket capacity and refill strategy
- Consider different tiers for different endpoint types
-
Implement rate limiting filter or interceptor
- Create
src/main/java/.../filters/RateLimitFilter.java:
- Extend
OncePerRequestFilter or implement HandlerInterceptor
- Extract client identifier (IP address, API key, or user ID)
- Maintain
ConcurrentHashMap<String, Bucket> for in-memory bucket storage
- Check bucket consumption before processing request
- Return HTTP 429 with
Retry-After header when limit exceeded
-
Apply rate limiting to controllers
- Protect public endpoints in
BooksController
- Consider different limits for read vs. write operations
- Option A: Apply filter globally via
FilterRegistrationBean
- Option B: Use custom annotation + AOP for selective rate limiting
-
Configure rate limit headers
- Add standard rate limit response headers:
X-RateLimit-Limit: Maximum requests allowed
X-RateLimit-Remaining: Remaining requests in current window
X-RateLimit-Reset: Time when the rate limit resets
Retry-After: Seconds until next request is allowed (on 429)
-
Add observability and logging
- Log rate limit events using SLF4J
- Include client identifier, endpoint, and timestamp
- Consider metrics integration for monitoring (future enhancement)
-
Externalize configuration
- Move rate limit values to
application.properties:
ratelimit.enabled=true
ratelimit.requests-per-minute=10
ratelimit.requests-per-hour=100
-
Key files to modify/create
pom.xml - Add Bucket4j dependency
src/main/java/.../config/RateLimitConfig.java - Rate limit configuration
src/main/java/.../filters/RateLimitFilter.java - Rate limiting filter
src/main/resources/application.properties - Rate limit settings
src/test/java/.../filters/RateLimitFilterTests.java - Filter unit tests
src/test/java/.../controllers/BooksControllerTests.java - Update integration tests
README.md - Document rate limiting behavior and configuration
-
Testing strategy
- Unit test the filter with mocked buckets
- Integration test controller endpoints with rapid requests
- Verify HTTP 429 status and headers
- Test bucket refill behavior over time
- Validate that legitimate traffic passes through
-
Documentation updates
- Update API documentation (OpenAPI/Swagger) with rate limit info
- Add rate limiting section to README.md
- Document configuration options and customization
- Include examples of rate limit responses
Acceptance Criteria
References
Problem
The project currently lacks protection against API abuse and excessive request rates. This leads to:
Without rate limiting, the API is exposed to abuse scenarios that can degrade performance, increase infrastructure costs, and compromise system availability.
Proposed Solution
Integrate Bucket4j as the rate-limiting library for the Spring Boot RESTful API. This will:
Suggested Approach
Add Bucket4j dependency
pom.xml:Create rate limit configuration class
src/main/java/.../config/RateLimitConfig.java:Implement rate limiting filter or interceptor
src/main/java/.../filters/RateLimitFilter.java:OncePerRequestFilteror implementHandlerInterceptorConcurrentHashMap<String, Bucket>for in-memory bucket storageRetry-Afterheader when limit exceededApply rate limiting to controllers
BooksControllerFilterRegistrationBeanConfigure rate limit headers
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Remaining requests in current windowX-RateLimit-Reset: Time when the rate limit resetsRetry-After: Seconds until next request is allowed (on 429)Add observability and logging
Externalize configuration
application.properties:Key files to modify/create
pom.xml- Add Bucket4j dependencysrc/main/java/.../config/RateLimitConfig.java- Rate limit configurationsrc/main/java/.../filters/RateLimitFilter.java- Rate limiting filtersrc/main/resources/application.properties- Rate limit settingssrc/test/java/.../filters/RateLimitFilterTests.java- Filter unit testssrc/test/java/.../controllers/BooksControllerTests.java- Update integration testsREADME.md- Document rate limiting behavior and configurationTesting strategy
Documentation updates
Acceptance Criteria
GET /books) is protected with rate limitingX-RateLimit-*,Retry-After)application.propertiesConcurrentHashMapReferences