fraiseql_server/config/
rate_limiting.rs1use serde::Deserialize;
4
5#[derive(Debug, Clone, Deserialize)]
7pub struct RateLimitingConfig {
8 #[serde(default = "default_enabled")]
10 pub enabled: bool,
11
12 pub default: String,
14
15 #[serde(default = "default_backend")]
17 pub backend: String,
18
19 pub redis_url_env: Option<String>,
21
22 #[serde(default)]
24 pub rules: Vec<RateLimitRule>,
25
26 #[serde(default)]
28 pub backpressure: BackpressureConfig,
29}
30
31const fn default_enabled() -> bool {
32 true
33}
34fn default_backend() -> String {
35 "memory".to_string()
36}
37
38#[derive(Debug, Clone, Deserialize)]
40pub struct RateLimitRule {
41 pub path: Option<String>,
43
44 pub mutation: Option<String>,
46
47 pub query: Option<String>,
49
50 pub limit: String,
52
53 #[serde(default = "default_key_by")]
55 pub by: String,
56
57 #[serde(default)]
59 pub burst: Option<u32>,
60}
61
62fn default_key_by() -> String {
63 "ip".to_string()
64}
65
66#[derive(Debug, Clone, Deserialize)]
68pub struct BackpressureConfig {
69 #[serde(default)]
71 pub queue_enabled: bool,
72
73 #[serde(default = "default_queue_size")]
75 pub max_queue_size: usize,
76
77 #[serde(default = "default_queue_timeout")]
79 pub queue_timeout: String,
80
81 #[serde(default = "default_load_shed")]
83 pub load_shed: bool,
84}
85
86impl Default for BackpressureConfig {
87 fn default() -> Self {
88 Self {
89 queue_enabled: false,
90 max_queue_size: default_queue_size(),
91 queue_timeout: default_queue_timeout(),
92 load_shed: default_load_shed(),
93 }
94 }
95}
96
97const fn default_queue_size() -> usize {
98 100
99}
100fn default_queue_timeout() -> String {
101 "5s".to_string()
102}
103const fn default_load_shed() -> bool {
104 true
105}