A flexible and configurable rate limiting service built with Spring Boot that supports different rate limit types and custom limits per endpoint.
- Configurable rate limits per endpoint
- Support for different time windows (second, day, week)
- Custom rate limit values per endpoint
- Header-based rate limit keys
- Redis-based rate limit storage
- Aspect-oriented rate limit enforcement
- Comprehensive test coverage
The service is built using the following components:
@RateLimit(key = "X-User-Id", type = "second", limit = 5)
key
: The HTTP header to use as the rate limit keytype
: The time window type (second/day/week)limit
: The maximum number of requests allowed in the time window
- RateLimitAspect: Handles rate limit checking using AOP
- RateLimiterService: Core service implementing rate limiting logic
- RateLimiterConfig: Configuration for default rate limits
- RedisTemplate: Used for distributed rate limit storage
@RestController
@RequestMapping("/api")
public class YourController {
@PostMapping("/resource")
@RateLimit(key = "X-User-Id", type = "second", limit = 10)
public ResponseEntity<String> yourEndpoint() {
// Your endpoint logic
}
}
In application.yml
:
rate-limiter:
max-requests-per-second: 2
max-requests-per-day: 10
max-requests-per-week: 5
When making requests to rate-limited endpoints, include the appropriate header:
curl -X POST http://your-api/resource \
-H "X-User-Id: user123"
-
Second-based Rate Limit
- Resets every second
- Example: 5 requests per second
-
Day-based Rate Limit
- Resets every 24 hours
- Example: 10 requests per day
-
Week-based Rate Limit
- Resets every 7 days
- Example: 1 request per week
200 OK
: Request allowed429 Too Many Requests
: Rate limit exceeded400 Bad Request
: Missing required header
The service includes comprehensive test coverage:
RateLimitAspectTest
: Tests the aspect's behaviorRateLimiterServiceTest
: Tests core rate limiting logic
RateLimiterIntegrationTest
: Tests complete HTTP request/response flow
Run tests:
mvn test
- Spring Boot
- Spring AOP
- Spring Data Redis
- Redis
- JUnit 5
- Mockito
The service includes a global exception handler for:
- Rate limit exceeded scenarios
- Missing headers
- Invalid rate limit types
-
Header Selection
- Use appropriate headers for rate limit keys
- Common choices: X-User-Id, X-IP-Address, X-Device-Id
-
Rate Limit Values
- Set reasonable limits based on your use case
- Consider using different limits for different endpoints
-
Time Windows
- Choose appropriate time windows for your use case
- Consider combining different time windows for stricter control
@RestController
@RequestMapping("/api")
public class RateLimiterController {
@PostMapping("/posts")
@RateLimit(key = "X-User-Id", type = "second", limit = 5)
public ResponseEntity<String> createPost() {
return ResponseEntity.ok("Post created successfully");
}
@PostMapping("/accounts")
@RateLimit(key = "X-IP-Address", type = "day", limit = 3)
public ResponseEntity<String> createAccount() {
return ResponseEntity.ok("Account created successfully");
}
@PostMapping("/rewards")
@RateLimit(key = "X-Device-Id", type = "week", limit = 1)
public ResponseEntity<String> claimReward() {
return ResponseEntity.ok("Reward claimed successfully");
}
}
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.