subgraph/graphql/entity/
mod.rs

1use async_graphql::dynamic::{Enum, Object};
2use log::debug;
3
4use crate::{
5    configuration::subgraph::{
6        entities::{service_entity_field::ServiceEntityFieldConfig, ServiceEntityConfig},
7        SubGraphConfig,
8    },
9    data_sources::{DataSource, DataSources},
10};
11
12mod create_as_type_field;
13mod create_field;
14pub mod create_return_types;
15pub mod get_field_type_ref;
16
17pub struct ServiceEntity {
18    data_sources: DataSources,
19    data_source: DataSource,
20    entity: ServiceEntityConfig,
21    type_name: String,
22    fields: Vec<ServiceEntityFieldConfig>,
23    subgraph_config: SubGraphConfig,
24    is_root: bool,
25}
26
27impl ServiceEntity {
28    pub fn new(
29        data_sources: DataSources,
30        entity: ServiceEntityConfig,
31        type_name: String,
32        fields: Vec<ServiceEntityFieldConfig>,
33        subgraph_config: SubGraphConfig,
34        is_root: Option<bool>,
35    ) -> Self {
36        let data_source = DataSources::get_entity_data_soruce(&data_sources, &entity);
37        Self {
38            data_sources: data_sources.clone(),
39            data_source: data_source.clone(),
40            entity,
41            type_name,
42            fields,
43            subgraph_config,
44            is_root: is_root.unwrap_or(true),
45        }
46    }
47
48    pub fn build(self) -> (Vec<Object>, Vec<Enum>) {
49        debug!("Creating Type For: `{}`", &self.type_name);
50
51        let mut type_defs = Vec::new();
52        let mut enum_defs = Vec::new();
53
54        let mut type_def = Object::new(&self.type_name);
55
56        // Before processing the fields, we need to create the return types
57        let return_types = self.create_return_types();
58        for return_type in return_types {
59            type_defs.push(return_type);
60        }
61
62        for entity_field in &self.fields {
63            if entity_field.exclude_from_output.unwrap_or(false) {
64                continue;
65            }
66
67            let type_defs_and_refs = self.get_field_type_ref(&entity_field);
68
69            for object_type_def in type_defs_and_refs.type_defs {
70                type_defs.push(object_type_def);
71            }
72
73            for enum_def in type_defs_and_refs.enum_defs {
74                enum_defs.push(enum_def);
75            }
76
77            if entity_field.as_type.is_some() {
78                let as_type_entity = match self.create_as_type_entity(entity_field) {
79                    Ok(as_type_entity) => as_type_entity,
80                    Err(_) => continue,
81                };
82                type_def = type_def.field(as_type_entity);
83            } else {
84                let field = ServiceEntity::create_field(
85                    entity_field.clone(),
86                    type_defs_and_refs.type_ref,
87                    self.data_source.clone(),
88                    self.is_root,
89                    self.entity.required.unwrap_or(false),
90                );
91                type_def = type_def.field(field);
92            }
93        }
94
95        type_defs.push(type_def);
96
97        debug!("Created Type Defs: {:?}", type_defs);
98
99        (type_defs, enum_defs)
100    }
101}