subgraph/graphql/entity/create_field/resolve_root/
mod.rs

1use async_graphql::{dynamic::ResolverContext, ErrorExtensions, Value};
2use bson::Document;
3use json::JsonValue;
4use log::{debug, error, trace};
5
6use crate::{
7    configuration::subgraph::entities::service_entity_field::ServiceEntityFieldConfig,
8    data_sources::{sql::services::ResponseRow, DataSource},
9    graphql::entity::ServiceEntity,
10    traits::async_graphql::FromJson,
11};
12
13impl ServiceEntity {
14    pub fn resolve_root(
15        ctx: &ResolverContext,
16        data_source: &DataSource,
17        entity_field: &ServiceEntityFieldConfig,
18        entity_required: bool,
19    ) -> Result<Option<Value>, async_graphql::Error> {
20        debug!("Resolve Root Field");
21        let field_name = ctx.field().name();
22        trace!("Field Name: {:?}", field_name);
23
24        let value = match data_source {
25            DataSource::Mongo(_ds) => {
26                let doc = match ctx.parent_value.try_downcast_ref::<Option<Document>>() {
27                    Ok(doc) => {
28                        trace!("Parent Value: {:?}", doc);
29                        if let Some(doc) = doc {
30                            trace!("Document Matched: {:?}", doc);
31                            let value = entity_field
32                                .scalar
33                                .clone()
34                                .document_field_to_async_graphql_value(doc, entity_field)?;
35                            trace!("Resolved Value: {:?}", value);
36                            Ok(value)
37                        } else {
38                            if entity_required {
39                                error!(
40                                    "Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity."
41                                );
42                                return Err(async_graphql::Error::new(
43                                    "Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.",
44                                )
45                                .extend_with(|_err, e| {
46                                    e.set("field", field_name);
47                                    e.set("entity", entity_field.name.clone());
48                                }));
49                            } else {
50                                trace!("Parent value is null, returning null.");
51                                if entity_required {
52                                    error!("Failed to resolve root field.");
53                                    return Err(async_graphql::Error::new(
54                                        "Failed to resolve root field.",
55                                    )
56                                    .extend_with(|_err, e| {
57                                        e.set("field", field_name);
58                                        e.set("entity", entity_field.name.clone());
59                                    }));
60                                } else {
61                                    trace!("Parent value is null, returning null.");
62                                    Ok(Some(Value::Null))
63                                }
64                            }
65                        }
66                    }
67                    Err(_) => {
68                        if entity_required {
69                            error!("Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.");
70                            return Err(async_graphql::Error::new("Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.")
71                                .extend_with(|_err, e| {
72                                    e.set("field", field_name);
73                                    e.set("entity", entity_field.name.clone());
74                                }));
75                        } else {
76                            trace!("Failed to downcast parent value, returning null.");
77                            return Ok(Some(Value::Null));
78                        }
79                    }
80                };
81
82                doc
83            }
84            DataSource::HTTP(_ds) => {
85                let json_value = match ctx.parent_value.try_downcast_ref::<JsonValue>() {
86                    Ok(json_value) => json_value,
87                    Err(_) => {
88                        if entity_required {
89                            error!("Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.");
90                            return Err(async_graphql::Error::new("Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.")
91                                .extend_with(|_err, e| {
92                                    e.set("field", field_name);
93                                    e.set("entity", entity_field.name.clone());
94                                }));
95                        } else {
96                            return Ok(Some(Value::Null));
97                        }
98                    }
99                };
100
101                let value = json_value.to_async_graphql_value();
102
103                Ok(Some(value))
104            }
105            DataSource::SQL(_ds) => {
106                let response_row = match ctx.parent_value.try_downcast_ref::<Option<ResponseRow>>()
107                {
108                    Ok(response_row) => {
109                        if let Some(rr) = response_row {
110                            let value = entity_field
111                                .scalar
112                                .clone()
113                                .rr_to_async_graphql_value(rr, field_name)?;
114                            Ok(Some(value))
115                        } else {
116                            if entity_required {
117                                error!(
118                                    "Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity"
119                                );
120                                return Err(async_graphql::Error::new(
121                                    "Failed to resolve root field. Entity is marked as required. This may be due to a join on a required entity.",
122                                )
123                                .extend_with(|_err, e| {
124                                    e.set("field", field_name);
125                                    e.set("entity", entity_field.name.clone());
126                                }));
127                            } else {
128                                trace!("Parent value is null, returning null.");
129                                Ok(Some(Value::Null))
130                            }
131                        }
132                    }
133                    Err(e) => {
134                        trace!("Failed to downcast parent value: {:?}", e);
135                        if entity_required {
136                            error!(
137                                "Failed to resolve root field, `{}`. Entity is marked as required. This may be due to a join on a required entity.",
138                                entity_field.name
139                            );
140                            return Err(async_graphql::Error::new(format!(
141                                "Failed to resolve root field, `{}`. The entity is marked as required. This may be due to a join on a required entity.",
142                                entity_field.name
143                            ))
144                            .extend_with(|_err, e| {
145                                e.set("field", field_name);
146                                e.set("entity", entity_field.name.clone());
147                            }));
148                        } else {
149                            return Ok(Some(Value::Null));
150                        }
151                    }
152                };
153                response_row
154            }
155        };
156
157        trace!("Resolved Root Field: {:?}", value);
158
159        value
160    }
161}