Skip to main content

fraiseql_core/config/
rate_limit.rs

1//! Rate limiting configuration.
2
3use serde::{Deserialize, Serialize};
4
5/// Rate limiting configuration.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(default)]
8pub struct RateLimitConfig {
9    /// Enable rate limiting.
10    pub enabled: bool,
11
12    /// Maximum requests per window.
13    pub requests_per_window: u32,
14
15    /// Window duration in seconds.
16    pub window_secs: u64,
17
18    /// Key extractor (ip, user, `api_key`).
19    pub key_by: RateLimitKey,
20
21    /// Paths to exclude from rate limiting.
22    pub exclude_paths: Vec<String>,
23
24    /// Custom limits per path pattern.
25    pub path_limits: Vec<PathRateLimit>,
26}
27
28impl Default for RateLimitConfig {
29    fn default() -> Self {
30        Self {
31            enabled:             false,
32            requests_per_window: 100,
33            window_secs:         60,
34            key_by:              RateLimitKey::Ip,
35            exclude_paths:       vec!["/health".to_string()],
36            path_limits:         vec![],
37        }
38    }
39}
40
41/// Rate limit key extractor.
42#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
43#[serde(rename_all = "snake_case")]
44#[non_exhaustive]
45pub enum RateLimitKey {
46    /// Rate limit by IP address.
47    #[default]
48    Ip,
49    /// Rate limit by authenticated user.
50    User,
51    /// Rate limit by API key.
52    ApiKey,
53}
54
55/// Per-path rate limit override.
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct PathRateLimit {
58    /// Path pattern (glob).
59    pub path:                String,
60    /// Maximum requests per window for this path.
61    pub requests_per_window: u32,
62}