subgraph/graphql/entity/create_field/resolve_root/
mod.rs1use 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}