Files
spring-boot-starter-erato-r…/README.md
2025-07-02 00:00:55 +03:00

5.8 KiB
Raw Blame History

Erato Rate Limit Spring Boot Starter

Redis tabanlı, mikroservis mimarisine uygun rate limiting kütüphanesi.

🚀 Kurulum

Maven

<dependency>
    <groupId>tr.com.erato</groupId>
    <artifactId>spring-boot-starter-rate-limit</artifactId>
    <version>1.0.0</version>
</dependency>

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

# 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

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

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/search")
    @RateLimit(limit = 60)  // Dakikada 60 istek
    public ResponseEntity<?> search() {
        // ...
    }
}

Gelişmiş Örnekler

// 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

@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

# 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

@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:

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:

# 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

@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

@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

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