Add README.md
This commit is contained in:
254
README.md
Normal file
254
README.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Erato Rate Limit Spring Boot Starter
|
||||
|
||||
Redis tabanlı, mikroservis mimarisine uygun rate limiting kütüphanesi.
|
||||
|
||||
## 🚀 Kurulum
|
||||
|
||||
### Maven
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>tr.com.erato</groupId>
|
||||
<artifactId>spring-boot-starter-rate-limit</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
Reference in New Issue
Block a user