Skip to content

Commit 3c723ab

Browse files
committed
move validation check to Query struct
Added Leaf-Field-Selections rule
1 parent fb8352a commit 3c723ab

File tree

11 files changed

+57
-43
lines changed

11 files changed

+57
-43
lines changed

Cargo.lock

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

graph/src/data/query/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use graphql_parser::Pos;
2+
use graphql_tools::validation::utils::ValidationError;
23
use hex::FromHexError;
34
use num_bigint;
45
use serde::ser::*;
@@ -297,6 +298,12 @@ impl From<QueryExecutionError> for Vec<QueryExecutionError> {
297298
}
298299
}
299300

301+
impl From<ValidationError> for QueryExecutionError {
302+
fn from(e: ValidationError) -> Self {
303+
QueryExecutionError::ValidationError(e.locations.clone().into_iter().nth(0), e.message)
304+
}
305+
}
306+
300307
impl From<FromHexError> for QueryExecutionError {
301308
fn from(e: FromHexError) -> Self {
302309
QueryExecutionError::ValueParseError("Bytes".to_string(), e.to_string())

graph/src/data/query/result.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use super::error::{QueryError, QueryExecutionError};
22
use crate::prelude::{r, CacheWeight, DeploymentHash};
3-
use graphql_tools::validation::utils::ValidationError;
43
use http::header::{
54
ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN,
65
CONTENT_TYPE,
@@ -183,7 +182,6 @@ pub struct QueryResult {
183182
data: Option<Data>,
184183
#[serde(skip_serializing_if = "Vec::is_empty")]
185184
errors: Vec<QueryError>,
186-
/// This is a non-standard GraphQL response field.
187185
#[serde(skip_serializing)]
188186
pub deployment: Option<DeploymentHash>,
189187
}
@@ -252,26 +250,6 @@ impl From<QueryExecutionError> for QueryResult {
252250
}
253251
}
254252

255-
impl From<Vec<ValidationError>> for QueryResult {
256-
fn from(errors: Vec<ValidationError>) -> Self {
257-
let execution_errors = errors
258-
.iter()
259-
.map(|e| {
260-
QueryError::ExecutionError(QueryExecutionError::ValidationError(
261-
e.locations.clone().into_iter().nth(0),
262-
e.message.clone(),
263-
))
264-
})
265-
.collect::<Vec<QueryError>>();
266-
267-
QueryResult {
268-
data: None,
269-
errors: execution_errors,
270-
deployment: None,
271-
}
272-
}
273-
}
274-
275253
impl From<QueryError> for QueryResult {
276254
fn from(e: QueryError) -> Self {
277255
QueryResult {

graphql/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ crossbeam = "0.8"
88
futures01 = { package="futures", version="0.1.29" }
99
graph = { path = "../graph" }
1010
graphql-parser = "0.4.0"
11-
graphql-tools = "0.0.6"
11+
graphql-tools = "0.0.8"
1212
indexmap = "1.7"
1313
Inflector = "0.11.3"
1414
lazy_static = "1.2.0"

graphql/src/execution/query.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use graphql_parser::Pos;
2+
use graphql_tools::validation::validate::{validate, ValidationPlan};
23
use std::collections::{HashMap, HashSet};
34
use std::hash::{Hash, Hasher};
45
use std::sync::Arc;
@@ -112,9 +113,19 @@ impl Query {
112113
schema: Arc<ApiSchema>,
113114
network: Option<String>,
114115
query: GraphDataQuery,
116+
validation_plan: Arc<ValidationPlan>,
115117
max_complexity: Option<u64>,
116118
max_depth: u8,
117119
) -> Result<Arc<Self>, Vec<QueryExecutionError>> {
120+
let validation_errors = validate(&schema.document(), &query.document, &validation_plan);
121+
122+
if validation_errors.len() > 0 {
123+
return Err(validation_errors
124+
.into_iter()
125+
.map(|e| QueryExecutionError::from(e))
126+
.collect());
127+
}
128+
118129
let mut operation = None;
119130
let mut fragments = HashMap::new();
120131
for defn in query.document.definitions.into_iter() {

graphql/src/runner.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::time::{Duration, Instant};
77
use crate::prelude::{QueryExecutionOptions, StoreResolver, SubscriptionExecutionOptions};
88
use crate::query::execute_query;
99
use crate::subscription::execute_prepared_subscription;
10-
use graph::prelude::{MetricsRegistry, QueryResult};
10+
use graph::prelude::MetricsRegistry;
1111
use graph::prometheus::{Gauge, Histogram};
1212
use graph::{
1313
components::store::SubscriptionManager,
@@ -22,10 +22,10 @@ use graph::{
2222
prelude::QueryStore,
2323
};
2424
use graphql_tools::validation::rules::{
25-
FragmentsOnCompositeTypes, KnownFragmentNamesRule, LoneAnonymousOperation, NoUnusedFragments,
26-
OverlappingFieldsCanBeMerged,
25+
FragmentsOnCompositeTypes, KnownFragmentNamesRule, LeafFieldSelections, LoneAnonymousOperation,
26+
NoUnusedFragments, OverlappingFieldsCanBeMerged,
2727
};
28-
use graphql_tools::validation::validate::{validate, ValidationPlan};
28+
use graphql_tools::validation::validate::ValidationPlan;
2929

3030
use lazy_static::lazy_static;
3131

@@ -82,7 +82,7 @@ pub struct GraphQlRunner<S, SM> {
8282
subscription_manager: Arc<SM>,
8383
load_manager: Arc<LoadManager>,
8484
result_size: Arc<ResultSizeMetrics>,
85-
graphql_validation_plan: ValidationPlan,
85+
pub graphql_validation_plan: Arc<ValidationPlan>,
8686
}
8787

8888
lazy_static! {
@@ -148,14 +148,15 @@ where
148148
graphql_validation_plan.add_rule(Box::new(OverlappingFieldsCanBeMerged {}));
149149
graphql_validation_plan.add_rule(Box::new(KnownFragmentNamesRule {}));
150150
graphql_validation_plan.add_rule(Box::new(NoUnusedFragments {}));
151+
graphql_validation_plan.add_rule(Box::new(LeafFieldSelections {}));
151152

152153
GraphQlRunner {
153154
logger,
154155
store,
155156
subscription_manager,
156157
load_manager,
157158
result_size,
158-
graphql_validation_plan,
159+
graphql_validation_plan: Arc::new(graphql_validation_plan),
159160
}
160161
}
161162

@@ -210,17 +211,6 @@ where
210211
// setting up here
211212
let store = self.store.query_store(target, false).await?;
212213
let schema = store.api_schema()?;
213-
214-
let validation_errors = validate(
215-
&schema.document(),
216-
&query.document,
217-
&self.graphql_validation_plan,
218-
);
219-
220-
if validation_errors.len() > 0 {
221-
return Ok(QueryResults::from(QueryResult::from(validation_errors)));
222-
}
223-
224214
let state = store.deployment_state().await?;
225215
let network = Some(store.network_name().to_string());
226216

@@ -238,6 +228,7 @@ where
238228
schema,
239229
network,
240230
query,
231+
self.graphql_validation_plan.clone(),
241232
max_complexity,
242233
max_depth,
243234
)?;
@@ -343,6 +334,7 @@ where
343334
schema,
344335
Some(network.clone()),
345336
subscription.query,
337+
self.graphql_validation_plan.clone(),
346338
*GRAPHQL_MAX_COMPLEXITY,
347339
*GRAPHQL_MAX_DEPTH,
348340
)?;

graphql/src/subscription/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::time::{Duration, Instant};
55

66
use graph::components::store::UnitStream;
77
use graph::{components::store::SubscriptionManager, prelude::*};
8+
use graphql_tools::validation::validate::ValidationPlan;
89

910
use crate::runner::ResultSizeMetrics;
1011
use crate::{
@@ -51,6 +52,7 @@ pub fn execute_subscription(
5152
schema,
5253
None,
5354
subscription.query,
55+
Arc::new(ValidationPlan { rules: vec![] }),
5456
options.max_complexity,
5557
options.max_depth,
5658
)?;

server/index-node/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ http = "0.2"
1414
hyper = "0.14"
1515
serde = "1.0"
1616
either = "1.6.1"
17+
graphql-tools = "0.0.8"

server/index-node/src/service.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use graphql_tools::validation::validate::ValidationPlan;
12
use http::header::{
23
self, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN,
34
CONTENT_TYPE, LOCATION,
@@ -113,7 +114,15 @@ where
113114
.await?;
114115

115116
let query = IndexNodeRequest::new(body).compat().await?;
116-
let query = match PreparedQuery::new(&self.logger, schema, None, query, None, 100) {
117+
let query = match PreparedQuery::new(
118+
&self.logger,
119+
schema,
120+
None,
121+
query,
122+
Arc::new(ValidationPlan { rules: vec![] }),
123+
None,
124+
100,
125+
) {
117126
Ok(query) => query,
118127
Err(e) => return Ok(QueryResults::from(QueryResult::from(e)).as_http_response()),
119128
};

store/test-store/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ lazy_static = "1.1"
1616
hex-literal = "0.3"
1717
diesel = { version = "1.4.8", features = ["postgres", "serde_json", "numeric", "r2d2"] }
1818
graph-chain-ethereum = { path = "../../chain/ethereum" }
19+
graphql-tools = "0.0.8"

0 commit comments

Comments
 (0)