Skip to main content

oxirs_gql/
features.rs

1//! Advanced GraphQL features
2//!
3//! This module provides advanced features like query optimization, introspection,
4//! validation, and performance enhancements.
5
6// Re-export advanced features
7pub use crate::introspection::*;
8pub use crate::optimizer::*;
9pub use crate::validation::*;
10
11/// Feature components
12pub mod components {
13    /// Individual feature components
14    /// Query optimization and caching
15    pub mod optimization {
16        pub use crate::optimizer::*;
17    }
18
19    /// GraphQL introspection
20    pub mod introspection {
21        pub use crate::introspection::*;
22    }
23
24    /// Query validation and security
25    pub mod validation {
26        pub use crate::validation::*;
27    }
28}
29
30/// Performance monitoring and metrics
31pub mod performance {
32    use std::collections::HashMap;
33    use std::time::{Duration, Instant};
34
35    /// Query performance metrics
36    #[derive(Debug, Clone)]
37    pub struct QueryMetrics {
38        pub query_hash: String,
39        pub execution_time: Duration,
40        pub complexity_score: usize,
41        pub depth: usize,
42        pub cache_hit: bool,
43        pub timestamp: Instant,
44    }
45
46    impl QueryMetrics {
47        pub fn new(
48            query_hash: String,
49            execution_time: Duration,
50            complexity_score: usize,
51            depth: usize,
52            cache_hit: bool,
53        ) -> Self {
54            Self {
55                query_hash,
56                execution_time,
57                complexity_score,
58                depth,
59                cache_hit,
60                timestamp: Instant::now(),
61            }
62        }
63    }
64
65    /// Performance tracker for collecting metrics
66    #[derive(Debug, Default)]
67    pub struct PerformanceTracker {
68        metrics: Vec<QueryMetrics>,
69        slow_queries: Vec<QueryMetrics>,
70        slow_query_threshold: Duration,
71    }
72
73    impl PerformanceTracker {
74        pub fn new() -> Self {
75            Self {
76                metrics: Vec::new(),
77                slow_queries: Vec::new(),
78                slow_query_threshold: Duration::from_millis(1000), // 1 second
79            }
80        }
81
82        pub fn with_slow_query_threshold(mut self, threshold: Duration) -> Self {
83            self.slow_query_threshold = threshold;
84            self
85        }
86
87        pub fn record_query(&mut self, metrics: QueryMetrics) {
88            if metrics.execution_time > self.slow_query_threshold {
89                self.slow_queries.push(metrics.clone());
90            }
91            self.metrics.push(metrics);
92        }
93
94        pub fn get_average_execution_time(&self) -> Option<Duration> {
95            if self.metrics.is_empty() {
96                return None;
97            }
98
99            let total: Duration = self.metrics.iter().map(|m| m.execution_time).sum();
100            Some(total / self.metrics.len() as u32)
101        }
102
103        pub fn get_cache_hit_rate(&self) -> f64 {
104            if self.metrics.is_empty() {
105                return 0.0;
106            }
107
108            let cache_hits = self.metrics.iter().filter(|m| m.cache_hit).count();
109            cache_hits as f64 / self.metrics.len() as f64
110        }
111
112        pub fn get_slow_queries(&self) -> &[QueryMetrics] {
113            &self.slow_queries
114        }
115
116        pub fn get_complexity_distribution(&self) -> HashMap<usize, usize> {
117            let mut distribution = HashMap::new();
118
119            for metric in &self.metrics {
120                let bucket = (metric.complexity_score / 100) * 100; // Group by hundreds
121                *distribution.entry(bucket).or_insert(0) += 1;
122            }
123
124            distribution
125        }
126    }
127}
128
129/// Security utilities
130pub mod security {
131
132    /// Common GraphQL security patterns
133    pub struct SecurityPatterns;
134
135    impl SecurityPatterns {
136        /// Check if query contains potentially dangerous patterns
137        pub fn has_dangerous_patterns(query: &str) -> bool {
138            let dangerous_keywords = [
139                "__schema",
140                "__type",
141                "mutation",
142                "subscription",
143                "introspection",
144            ];
145
146            let query_lower = query.to_lowercase();
147            dangerous_keywords
148                .iter()
149                .any(|&keyword| query_lower.contains(keyword))
150        }
151
152        /// Extract operation names from a query
153        pub fn extract_operation_names(query: &str) -> Vec<String> {
154            // This is a simplified implementation
155            // In practice, you'd want to parse the query properly
156            let mut operations = Vec::new();
157
158            for line in query.lines() {
159                let line = line.trim();
160                if line.starts_with("query ")
161                    || line.starts_with("mutation ")
162                    || line.starts_with("subscription ")
163                {
164                    if let Some(name_start) = line.find(' ') {
165                        if let Some(name_end) = line[name_start + 1..].find([' ', '(', '{']) {
166                            let name = &line[name_start + 1..name_start + 1 + name_end];
167                            if !name.is_empty() {
168                                operations.push(name.to_string());
169                            }
170                        }
171                    }
172                }
173            }
174
175            operations
176        }
177
178        /// Get recommended security settings for different environments
179        pub fn recommended_validation_config(
180            environment: Environment,
181        ) -> crate::validation::ValidationConfig {
182            match environment {
183                Environment::Development => crate::validation::ValidationConfig {
184                    max_depth: 15,
185                    max_complexity: 2000,
186                    max_aliases: 100,
187                    max_root_fields: 50,
188                    disable_introspection: false,
189                    max_fragments: 100,
190                    ..Default::default()
191                },
192                Environment::Production => crate::validation::ValidationConfig {
193                    max_depth: 8,
194                    max_complexity: 1000,
195                    max_aliases: 20,
196                    max_root_fields: 15,
197                    disable_introspection: true,
198                    max_fragments: 25,
199                    ..Default::default()
200                },
201                Environment::Testing => crate::validation::ValidationConfig {
202                    max_depth: 20,
203                    max_complexity: 5000,
204                    max_aliases: 200,
205                    max_root_fields: 100,
206                    disable_introspection: false,
207                    max_fragments: 200,
208                    ..Default::default()
209                },
210            }
211        }
212    }
213
214    /// Deployment environment
215    #[derive(Debug, Clone, Copy)]
216    pub enum Environment {
217        Development,
218        Production,
219        Testing,
220    }
221}