Skip to content

Commit 80b733b

Browse files
federation 2.11 (#633)
2 parents 3510bf6 + e6a3f54 commit 80b733b

File tree

4 files changed

+107
-72
lines changed

4 files changed

+107
-72
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ members = ["apollo-federation-types", "apollo-composition"]
33
resolver = "2"
44

55
[workspace.dependencies]
6-
apollo-compiler = "1.0.0-beta.24"
6+
apollo-compiler = "1.28.0"

apollo-composition/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "apollo-composition"
3-
version = "0.2.7"
3+
version = "0.3.0"
44
license = "Elastic-2.0"
55
edition = "2021"
66
authors = ["Apollo Developers <[email protected]>"]
@@ -10,7 +10,7 @@ repository = "https://github.com/apollographql/federation-rs/"
1010

1111
[dependencies]
1212
apollo-compiler = { workspace = true }
13-
apollo-federation = "=2.1.2"
13+
apollo-federation = { version = "=2.3.0" }
1414
apollo-federation-types = { version = "0.15.3", path = "../apollo-federation-types", features = [
1515
"composition",
1616
] }

apollo-composition/src/lib.rs

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22
use std::iter::once;
33

4-
use apollo_compiler::schema::ExtendedType;
4+
use apollo_compiler::{schema::ExtendedType, Schema};
55
use apollo_federation::sources::connect::{
66
expand::{expand_connectors, Connectors, ExpansionResult},
77
validation::{validate, Severity as ValidationSeverity, ValidationResult},
@@ -66,37 +66,43 @@ pub trait HybridComposition {
6666
/// 3. Run Rust-based validation on the supergraph
6767
/// 4. Call [`validate_satisfiability`] to run JavaScript-based validation on the supergraph
6868
async fn compose(&mut self, subgraph_definitions: Vec<SubgraphDefinition>) {
69-
let validation_results = subgraph_definitions
70-
.iter()
71-
.map(|subgraph| {
72-
(
73-
subgraph.name.clone(),
74-
validate(&subgraph.sdl, &subgraph.name),
75-
)
76-
})
77-
.collect::<Vec<_>>();
78-
let subgraph_validation_errors = validation_results
79-
.iter()
80-
.flat_map(|(name, validation_result)| {
81-
validation_result
82-
.errors
83-
.iter()
84-
.cloned()
85-
.map(|validation_error| Issue {
86-
code: validation_error.code.to_string(),
87-
message: validation_error.message,
88-
locations: validation_error
69+
let mut subgraph_validation_errors = Vec::new();
70+
let mut parsed_schemas = HashMap::new();
71+
let subgraph_definitions = subgraph_definitions
72+
.into_iter()
73+
.map(|mut subgraph| {
74+
let ValidationResult {
75+
errors,
76+
has_connectors,
77+
schema,
78+
transformed,
79+
} = validate(subgraph.sdl, &subgraph.name);
80+
subgraph.sdl = transformed;
81+
for error in errors {
82+
subgraph_validation_errors.push(Issue {
83+
code: error.code.to_string(),
84+
message: error.message,
85+
locations: error
8986
.locations
9087
.into_iter()
9188
.map(|range| SubgraphLocation {
92-
subgraph: Some(name.clone()),
89+
subgraph: Some(subgraph.name.clone()),
9390
range: Some(range),
9491
})
9592
.collect(),
96-
severity: convert_severity(validation_error.code.severity()),
93+
severity: convert_severity(error.code.severity()),
9794
})
95+
}
96+
parsed_schemas.insert(
97+
subgraph.name.clone(),
98+
SubgraphSchema {
99+
schema,
100+
has_connectors,
101+
},
102+
);
103+
subgraph
98104
})
99-
.collect::<Vec<_>>();
105+
.collect();
100106

101107
let run_composition = subgraph_validation_errors
102108
.iter()
@@ -115,7 +121,7 @@ pub trait HybridComposition {
115121

116122
// Any issues with overrides are fatal since they'll cause errors in expansion,
117123
// so we return early if we see any.
118-
let override_errors = validate_overrides(validation_results);
124+
let override_errors = validate_overrides(parsed_schemas);
119125
if !override_errors.is_empty() {
120126
self.add_issues(override_errors.into_iter());
121127
return;
@@ -168,16 +174,20 @@ pub trait HybridComposition {
168174
}
169175
}
170176

177+
struct SubgraphSchema {
178+
schema: Schema,
179+
has_connectors: bool,
180+
}
181+
171182
/// Validate overrides for connector-related subgraphs
172183
///
173184
/// Overrides mess with the supergraph in ways that can be difficult to detect when
174185
/// expanding connectors; the supergraph may omit overridden fields and other shenanigans.
175186
/// To allow for a better developer experience, we check here if any connector-enabled subgraphs
176187
/// have fields overridden.
177-
fn validate_overrides(schemas: impl IntoIterator<Item = (String, ValidationResult)>) -> Vec<Issue> {
178-
let validations_by_subgraph_name = HashMap::<_, _>::from_iter(schemas);
188+
fn validate_overrides(schemas: HashMap<String, SubgraphSchema>) -> Vec<Issue> {
179189
let mut override_errors = Vec::new();
180-
for (subgraph_name, ValidationResult { schema, .. }) in validations_by_subgraph_name.iter() {
190+
for (subgraph_name, SubgraphSchema { schema, .. }) in &schemas {
181191
// We need to grab all fields in the schema since only fields can have the @override
182192
// directive attached
183193
macro_rules! extract_directives {
@@ -218,32 +228,31 @@ fn validate_overrides(schemas: impl IntoIterator<Item = (String, ValidationResul
218228
for (field, directive) in override_directives {
219229
// If the override directive does not have a valid `from` field, then there is
220230
// no point trying to validate it, as later steps will validate the entire schema.
221-
let Ok(Some(overriden_subgraph_name)) = directive
231+
let Ok(Some(overridden_subgraph_name)) = directive
222232
.argument_by_name("from", schema)
223233
.map(|node| node.as_str())
224234
else {
225235
continue;
226236
};
227237

228-
if let Some(overriden_subgraph) =
229-
validations_by_subgraph_name.get(overriden_subgraph_name)
238+
if schemas
239+
.get(overridden_subgraph_name)
240+
.is_some_and(|schema| schema.has_connectors)
230241
{
231-
if overriden_subgraph.has_connectors {
232-
override_errors.push(Issue {
242+
override_errors.push(Issue {
233243
code: "OVERRIDE_ON_CONNECTOR".to_string(),
234244
message: format!(
235245
r#"Field "{}" on subgraph "{}" is trying to override connector-enabled subgraph "{}", which is not yet supported. See https://go.apollo.dev/connectors/limitations#override-is-partially-unsupported"#,
236246
field,
237247
subgraph_name,
238-
overriden_subgraph_name,
248+
overridden_subgraph_name,
239249
),
240250
locations: vec![SubgraphLocation {
241-
subgraph: Some(subgraph_name.clone()),
251+
subgraph: Some(String::from(overridden_subgraph_name)),
242252
range: directive.line_column_range(&schema.sources),
243253
}],
244254
severity: Severity::Error,
245255
});
246-
}
247256
}
248257
}
249258
}

0 commit comments

Comments
 (0)