1use std::time::Duration;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct AuthConfig {
6 pub secret: String,
8 pub public_paths: Vec<String>,
10}
11
12impl AuthConfig {
13 pub fn is_public(&self, path: &str) -> bool {
15 self.public_paths.iter().any(|item| item == path)
16 }
17}
18
19#[derive(Debug, Clone)]
21pub struct RestConfig {
22 pub name: String,
24 pub timeout: Duration,
26 pub max_body_bytes: usize,
28 pub auth: Option<AuthConfig>,
30 pub middlewares: RestMiddlewareConfig,
32 #[cfg(feature = "observability")]
34 pub metrics_registry: Option<crate::observability::MetricsRegistry>,
35}
36
37impl Default for RestConfig {
38 fn default() -> Self {
39 Self {
40 name: "rs-zero".to_string(),
41 timeout: Duration::from_secs(5),
42 max_body_bytes: 1024 * 1024,
43 auth: None,
44 middlewares: RestMiddlewareConfig::default(),
45 #[cfg(feature = "observability")]
46 metrics_registry: None,
47 }
48 }
49}
50
51impl RestConfig {
52 pub fn go_zero_defaults(name: impl Into<String>) -> Self {
54 Self {
55 name: name.into(),
56 middlewares: RestMiddlewareConfig {
57 resilience: RestResilienceConfig::go_zero_defaults(),
58 metrics: RestMetricsConfig { enabled: true },
59 },
60 ..Self::default()
61 }
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Default)]
67pub struct RestMiddlewareConfig {
68 pub resilience: RestResilienceConfig,
70 pub metrics: RestMetricsConfig,
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct RestResilienceConfig {
77 pub breaker_enabled: bool,
79 pub breaker_failure_threshold: u32,
81 pub breaker_reset_timeout: Duration,
83 pub breaker_sre_enabled: bool,
85 pub breaker_sre_k_millis: u32,
87 pub breaker_sre_protection: u64,
89 pub max_concurrency: Option<usize>,
91 pub request_timeout: Option<Duration>,
93 pub shedding_enabled: bool,
95 pub shedding_max_in_flight: Option<usize>,
97 pub shedding_min_request_count: u64,
99 pub shedding_max_latency: Duration,
101 pub shedding_cpu_threshold_millis: u32,
103 pub shedding_cool_off: Duration,
105 pub shedding_window_buckets: usize,
107 pub shedding_window_bucket_duration: Duration,
109 #[cfg(all(feature = "resil", feature = "cache-redis"))]
111 pub rate_limiter: RestRateLimiterConfig,
112}
113
114impl Default for RestResilienceConfig {
115 fn default() -> Self {
116 Self {
117 breaker_enabled: false,
118 breaker_failure_threshold: 5,
119 breaker_reset_timeout: Duration::from_secs(30),
120 breaker_sre_enabled: false,
121 breaker_sre_k_millis: 1500,
122 breaker_sre_protection: 5,
123 max_concurrency: None,
124 request_timeout: None,
125 shedding_enabled: false,
126 shedding_max_in_flight: None,
127 shedding_min_request_count: 20,
128 shedding_max_latency: Duration::from_millis(250),
129 shedding_cpu_threshold_millis: 900,
130 shedding_cool_off: Duration::from_secs(1),
131 shedding_window_buckets: 50,
132 shedding_window_bucket_duration: Duration::from_millis(100),
133 #[cfg(all(feature = "resil", feature = "cache-redis"))]
134 rate_limiter: RestRateLimiterConfig::default(),
135 }
136 }
137}
138
139impl RestResilienceConfig {
140 pub fn go_zero_defaults() -> Self {
142 Self {
143 breaker_enabled: true,
144 breaker_sre_enabled: true,
145 max_concurrency: Some(1024),
146 request_timeout: Some(Duration::from_secs(5)),
147 shedding_enabled: true,
148 shedding_max_in_flight: Some(1024),
149 shedding_min_request_count: 20,
150 shedding_max_latency: Duration::from_millis(250),
151 ..Self::default()
152 }
153 }
154}
155
156#[cfg(all(feature = "resil", feature = "cache-redis"))]
158#[derive(Debug, Clone, PartialEq, Eq, Default)]
159pub enum RestRateLimiterConfig {
160 #[default]
162 Disabled,
163 RedisToken(crate::resil::RedisTokenLimiterConfig),
165 RedisPeriod(crate::resil::RedisPeriodLimiterConfig),
167}
168
169#[derive(Debug, Clone, PartialEq, Eq, Default)]
171pub struct RestMetricsConfig {
172 pub enabled: bool,
174}