Skip to content

Commit 1a8e3b4

Browse files
fix(federation): added the remove_introspection step in normalize_operation (#5580)
Co-authored-by: Renée <[email protected]>
1 parent 27a3e1d commit 1a8e3b4

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

apollo-federation/src/operation/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4901,6 +4901,7 @@ pub(crate) fn normalize_operation(
49014901
schema,
49024902
NormalizeSelectionOption::NormalizeRecursively,
49034903
)?;
4904+
remove_introspection(&mut normalized_selection_set);
49044905
normalized_selection_set.optimize_sibling_typenames(interface_types_with_interface_objects)?;
49054906

49064907
let normalized_operation = Operation {
@@ -4915,6 +4916,21 @@ pub(crate) fn normalize_operation(
49154916
Ok(normalized_operation)
49164917
}
49174918

4919+
// PORT_NOTE: This is a port of `withoutIntrospection` from JS version.
4920+
fn remove_introspection(selection_set: &mut SelectionSet) {
4921+
// Note that, because we only apply this to the top-level selections, we skip all
4922+
// introspection, including __typename. In general, we don't want to ignore __typename during
4923+
// query plans, but at top-level, we can let the router execution deal with it rather than
4924+
// querying some service for that.
4925+
4926+
Arc::make_mut(&mut selection_set.selections).retain(|_, selection| {
4927+
!matches!(selection,
4928+
Selection::Field(field_selection) if
4929+
field_selection.field.field_position.is_introspection_typename_field()
4930+
)
4931+
});
4932+
}
4933+
49184934
fn runtime_types_intersect(
49194935
type1: &CompositeTypeDefinitionPosition,
49204936
type2: &CompositeTypeDefinitionPosition,

apollo-federation/src/query_plan/query_planner.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,4 +1313,51 @@ type User
13131313
}
13141314
"###);
13151315
}
1316+
1317+
#[test]
1318+
fn drop_operation_root_level_typename() {
1319+
let subgraph1 = Subgraph::parse_and_expand(
1320+
"Subgraph1",
1321+
"https://Subgraph1",
1322+
r#"
1323+
type Query {
1324+
t: T
1325+
}
1326+
1327+
type T @key(fields: "id") {
1328+
id: ID!
1329+
x: Int
1330+
}
1331+
"#,
1332+
)
1333+
.unwrap();
1334+
let subgraphs = vec![&subgraph1];
1335+
let supergraph = Supergraph::compose(subgraphs).unwrap();
1336+
let planner = QueryPlanner::new(&supergraph, Default::default()).unwrap();
1337+
let document = ExecutableDocument::parse_and_validate(
1338+
planner.api_schema().schema(),
1339+
r#"
1340+
query {
1341+
__typename
1342+
t {
1343+
x
1344+
}
1345+
}
1346+
"#,
1347+
"operation.graphql",
1348+
)
1349+
.unwrap();
1350+
let plan = planner.build_query_plan(&document, None).unwrap();
1351+
insta::assert_snapshot!(plan, @r###"
1352+
QueryPlan {
1353+
Fetch(service: "Subgraph1") {
1354+
{
1355+
t {
1356+
x
1357+
}
1358+
}
1359+
},
1360+
}
1361+
"###);
1362+
}
13161363
}

0 commit comments

Comments
 (0)