Skip to main content

ferrox_graphql/
lib.rs

1use async_graphql::{EmptyMutation, EmptySubscription, Object, Schema};
2use std::sync::Arc;
3
4/// A simple GraphQL Query root for demonstration.
5/// In a real scenario, this would be constructed dynamically or composed of multiple Query roots.
6pub struct QueryRoot;
7
8#[Object]
9impl QueryRoot {
10    /// A simple health check query
11    async fn ping(&self) -> &'static str {
12        "pong"
13    }
14}
15
16/// Helper to build a basic Ferrox GraphQL schema without mutations or subscriptions
17pub fn build_schema() -> Schema<QueryRoot, EmptyMutation, EmptySubscription> {
18    Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish()
19}
20
21/// Helper to build a GraphQL schema with a Repository injected into its context
22pub fn build_schema_with_context<T: Send + Sync + 'static>(
23    repo: Arc<T>,
24) -> Schema<QueryRoot, EmptyMutation, EmptySubscription> {
25    Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
26        .data(repo)
27        .finish()
28}
29
30/// Helper to export the GraphQL Schema (SDL) to a file for Frontend Code Generation
31pub fn export_sdl<Q, M, S>(schema: &Schema<Q, M, S>, path: &str) -> Result<(), std::io::Error> 
32where
33    Q: async_graphql::ObjectType + 'static,
34    M: async_graphql::ObjectType + 'static,
35    S: async_graphql::SubscriptionType + 'static,
36{
37    let sdl = schema.sdl();
38    std::fs::write(path, sdl)?;
39    println!("✅ GraphQL Schema successfully exported to {}", path);
40    Ok(())
41}
42
43pub fn setup() {
44    println!("ferrox-graphql initialized: Provides async-graphql Schema builders.");
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use async_graphql::value;
51    use serde_json::json;
52
53    // TDD: Verify that we can build a schema and execute a query without any reflection overhead
54    #[tokio::test]
55    async fn test_graphql_ping_query() {
56        let schema = build_schema();
57
58        let request = "{ ping }";
59        let response = schema.execute(request).await;
60
61        assert_eq!(
62            response.data.into_json().unwrap(),
63            json!({
64                "ping": "pong"
65            })
66        );
67    }
68}