subgraph/graphql/schema/
mod.rs

1use async_graphql::dynamic::{
2    Field, FieldFuture, FieldValue, Object, Scalar, Schema, SchemaBuilder, TypeRef,
3};
4use biscuit_auth::KeyPair;
5use log::{debug, error, trace};
6
7use crate::{configuration::subgraph::SubGraphConfig, data_sources::DataSources};
8
9pub mod create_auth_service;
10pub mod create_entities;
11pub mod create_options_input;
12
13pub struct ServiceSchema {
14    pub subgraph_config: SubGraphConfig,
15    pub schema_builder: SchemaBuilder,
16    pub query: Object,
17    pub mutation: Object,
18    pub data_sources: DataSources,
19    pub key_pair: Option<KeyPair>,
20}
21
22impl ServiceSchema {
23    pub fn new(subgraph_config: SubGraphConfig, data_sources: DataSources) -> Self {
24        debug!("Creating Service Schema");
25
26        let service_schema = ServiceSchema {
27            subgraph_config,
28            schema_builder: Schema::build("Query", Some("Mutation"), None),
29            query: Object::new("Query").extends(),
30            mutation: Object::new("Mutation"),
31            data_sources,
32            key_pair: None,
33        };
34        debug!("Service Schema Initialized");
35        service_schema
36    }
37
38    pub fn register_health_check(mut self) -> Self {
39        debug!("Registering Health Check");
40        self.query = self.query.field(Field::new(
41            "health_check",
42            TypeRef::named_nn(TypeRef::BOOLEAN),
43            move |_| FieldFuture::new(async move { Ok(Some(FieldValue::owned_any(true))) }),
44        ));
45        self.mutation = self.mutation.field(Field::new(
46            "create_health_check",
47            TypeRef::named_nn(TypeRef::BOOLEAN),
48            move |_| FieldFuture::new(async move { Ok(Some(FieldValue::owned_any(true))) }),
49        ));
50        self
51    }
52
53    pub fn build(mut self) -> Schema {
54        debug!("Building Schema");
55
56        // Check for key pair and create if needed
57        self.get_key_pair();
58
59        // Create shared options input
60        self = self.create_options_input();
61
62        // Create entities
63        self = self.create_entities();
64
65        // Create Health Check
66        self = self.register_health_check();
67
68        // Create auth service
69        if self.subgraph_config.service.auth.is_some() {
70            self = self.create_auth_service();
71        }
72
73        // List scalars
74        let object_id = Scalar::new("ObjectID");
75
76        // Register Query and Mutation
77        let schema = self
78            .schema_builder
79            .data(self.data_sources.clone())
80            .data(self.key_pair)
81            .enable_federation()
82            .register(object_id)
83            .register(self.query)
84            .register(self.mutation)
85            .finish();
86
87        trace!("{:?}", schema);
88
89        match schema {
90            Ok(sch) => sch,
91            Err(err) => {
92                error!("{}", err);
93                panic!("Failed to build schema.")
94            }
95        }
96    }
97}