diff --git a/README.md b/README.md new file mode 100644 index 0000000..01ba28b --- /dev/null +++ b/README.md @@ -0,0 +1,254 @@ +# Erato Rate Limit Spring Boot Starter + +Redis tabanlı, mikroservis mimarisine uygun rate limiting kütüphanesi. + +## 🚀 Kurulum + +### Maven +```xml + + tr.com.erato + spring-boot-starter-rate-limit + 1.0.0 + +``` + +### Gradle +```gradle +implementation 'tr.com.erato:spring-boot-starter-rate-limit:1.0.0' +``` + +## 📋 Gereksinimler + +- Spring Boot 3.0+ +- Java 17+ +- Redis +- Spring Web MVC + +## ⚙️ Yapılandırma + +### application.properties +```properties +# Redis yapılandırması (zaten mevcut) +spring.data.redis.host=localhost +spring.data.redis.port=6379 + +# Rate Limit yapılandırması +erato.rate-limit.enabled=true +erato.rate-limit.redis-key-prefix=rate_limit: +erato.rate-limit.include-headers=true +erato.rate-limit.default-limit=60 +erato.rate-limit.default-window=MINUTE + +# Path yapılandırması +erato.rate-limit.include-patterns=/api/** +erato.rate-limit.exclude-patterns=/api/health/**,/actuator/** + +# Admin endpoint +erato.rate-limit.admin-enabled=true +erato.rate-limit.admin-base-path=/api/admin/rate-limits + +# Error response +erato.rate-limit.error-response.message=Rate limit aşıldı +erato.rate-limit.error-response.include-retry-after=true +``` + +### application.yml +```yaml +erato: + rate-limit: + enabled: true + redis-key-prefix: "rate_limit:" + include-headers: true + default-limit: 60 + default-window: MINUTE + include-patterns: + - "/api/**" + exclude-patterns: + - "/api/health/**" + - "/actuator/**" + admin-enabled: true + error-response: + message: "Rate limit aşıldı" + include-retry-after: true +``` + +## 🎯 Kullanım + +### Basit Kullanım + +```java +@RestController +@RequestMapping("/api") +public class MyController { + + @GetMapping("/search") + @RateLimit(limit = 60) // Dakikada 60 istek + public ResponseEntity search() { + // ... + } +} +``` + +### Gelişmiş Örnekler + +```java +// IP bazlı, saatte 10 istek +@RateLimit(limit = 10, window = TimeWindow.HOUR, type = RateLimitType.IP) + +// Kullanıcı bazlı, günde 100 istek +@RateLimit(limit = 100, window = TimeWindow.DAY, type = RateLimitType.USER) + +// Global limit, saniyede 1000 istek +@RateLimit(limit = 1000, window = TimeWindow.SECOND, type = RateLimitType.GLOBAL) + +// Özel mesaj ile +@RateLimit(limit = 5, message = "Çok fazla deneme yaptınız") +``` + +### Sınıf Seviyesinde Rate Limit + +```java +@RestController +@RequestMapping("/api/users") +@RateLimit(limit = 100, window = TimeWindow.MINUTE) +public class UserController { + // Tüm metodlar bu limiti kullanır +} +``` + +## 🎨 Preset Kullanımı + +Sık kullanılan rate limit kombinasyonlarını preset olarak tanımlayabilirsiniz: + +### application.properties +```properties +# Login preset +erato.rate-limit.presets.strict-login.limit=5 +erato.rate-limit.presets.strict-login.window=MINUTE +erato.rate-limit.presets.strict-login.type=IP +erato.rate-limit.presets.strict-login.message=Çok fazla giriş denemesi + +# API preset +erato.rate-limit.presets.standard-api.limit=100 +erato.rate-limit.presets.standard-api.window=MINUTE +erato.rate-limit.presets.standard-api.type=USER +``` + +### Kullanım +```java +@PostMapping("/login") +@RateLimit(preset = "strict-login") +public ResponseEntity login() { + // ... +} + +@GetMapping("/data") +@RateLimit(preset = "standard-api") +public ResponseEntity getData() { + // ... +} +``` + +## 📊 HTTP Headers + +Rate limit bilgileri response header'larında döner: + +```http +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 45 +X-RateLimit-Reset: 1640995200 +Retry-After: 30 (sadece 429 durumunda) +``` + +## 🛠️ Admin API + +Admin kullanıcıları için yönetim endpoint'leri otomatik olarak eklenir: + +```bash +# Tüm rate limitleri görüntüle +GET /api/admin/rate-limits + +# İstatistikleri görüntüle +GET /api/admin/rate-limits/stats + +# Belirli bir rate limit'i sıfırla +DELETE /api/admin/rate-limits/{key} + +# Tüm rate limitleri sıfırla +DELETE /api/admin/rate-limits +``` + +## 🔧 Özelleştirme + +### Custom Key Builder + +```java +@Component +public class CustomKeyBuilder implements RateLimitKeyBuilder { + @Override + public String buildKey(HttpServletRequest request, RateLimit rateLimit) { + // Özel key oluşturma mantığı + return "custom:" + request.getHeader("X-API-Key"); + } +} +``` + +### Event Listener + +```java +@Component +public class RateLimitEventListener { + + @EventListener + public void onRateLimitExceeded(RateLimitExceededEvent event) { + log.warn("Rate limit exceeded: {}", event.getKey()); + // Bildirim gönder, metrik kaydet vs. + } +} +``` + +## 📈 Monitoring + +### Actuator Integration + +```properties +management.endpoints.web.exposure.include=health,metrics,ratelimit +``` + +Endpoint: `GET /actuator/ratelimit` + +### Metrics + +Otomatik olarak Micrometer metrikleri sağlanır: + +- `rate.limit.requests.total` - Toplam istek sayısı +- `rate.limit.exceeded.total` - Rate limit aşım sayısı +- `rate.limit.active.keys` - Aktif rate limit key sayısı + +## 🏗️ Proje Yapısı + +``` +erato-rate-limit-spring-boot-starter/ +├── src/main/java/tr/com/erato/RateLimit/ +│ ├── annotation/ # Anotasyonlar +│ ├── config/ # Auto-configuration +│ ├── controller/ # Admin controller +│ ├── interceptor/ # HTTP interceptor +│ ├── model/ # Model sınıfları +│ └── service/ # Core servisler +└── src/main/resources/ + └── META-INF/ + ├── spring.factories + └── spring/ + └── org.springframework.boot.autoconfigure.AutoConfiguration.imports +``` + +## 🤝 Katkıda Bulunma + +1. Fork edin +2. Feature branch oluşturun (`git checkout -b feature/amazing-feature`) +3. Commit edin (`git commit -m 'Add some amazing feature'`) +4. Push edin (`git push origin feature/amazing-feature`) +5. Pull Request açın +