diff --git a/apollo-router/src/configuration/metrics.rs b/apollo-router/src/configuration/metrics.rs index ed8263aecd..6ea8121a69 100644 --- a/apollo-router/src/configuration/metrics.rs +++ b/apollo-router/src/configuration/metrics.rs @@ -49,6 +49,7 @@ impl Metrics { data.populate_user_plugins_instrument(configuration); data.populate_query_planner_experimental_parallelism(configuration); data.populate_deno_or_rust_mode_instruments(configuration); + data.populate_legacy_fragment_usage(configuration); data.into() } @@ -497,6 +498,18 @@ impl InstrumentData { ); } + pub(crate) fn populate_legacy_fragment_usage(&mut self, configuration: &Configuration) { + // Fragment generation takes precedence over fragment reuse. Only report when fragment reuse is *actually active*. + if configuration.supergraph.reuse_query_fragments == Some(true) + && !configuration.supergraph.generate_query_fragments + { + self.data.insert( + "apollo.router.config.reuse_query_fragments".to_string(), + (1, HashMap::new()), + ); + } + } + pub(crate) fn populate_query_planner_experimental_parallelism( &mut self, configuration: &Configuration, diff --git a/apollo-router/src/configuration/mod.rs b/apollo-router/src/configuration/mod.rs index 985c1d6702..724237ece5 100644 --- a/apollo-router/src/configuration/mod.rs +++ b/apollo-router/src/configuration/mod.rs @@ -394,7 +394,7 @@ impl Configuration { pub(crate) fn js_query_planner_config(&self) -> router_bridge::planner::QueryPlannerConfig { router_bridge::planner::QueryPlannerConfig { - reuse_query_fragments: None, + reuse_query_fragments: self.supergraph.reuse_query_fragments, generate_query_fragments: Some(self.supergraph.generate_query_fragments), incremental_delivery: Some(router_bridge::planner::IncrementalDeliverySupport { enable_defer: Some(self.supergraph.defer_support), @@ -416,6 +416,14 @@ impl Configuration { pub(crate) fn rust_query_planner_config( &self, ) -> apollo_federation::query_plan::query_planner::QueryPlannerConfig { + if self + .supergraph + .reuse_query_fragments + .is_some_and(|flag| flag) + { + // warn the user that reuse query fragments is unsupported for RS QP + tracing::warn!("'experimental_reuse_query_fragments' is not supported by the Rust QP and this configuration option will be removed in the next release. Use 'generate_query_fragments' instead."); + } apollo_federation::query_plan::query_planner::QueryPlannerConfig { subgraph_graphql_validation: false, generate_query_fragments: self.supergraph.generate_query_fragments, @@ -682,6 +690,13 @@ pub(crate) struct Supergraph { /// Default: false pub(crate) introspection: bool, + /// Enable reuse of query fragments + /// + /// This feature is deprecated and will be removed in next release. It is only available in JS QP. + /// Use generate_query_fragments instead. + #[serde(rename = "experimental_reuse_query_fragments")] + pub(crate) reuse_query_fragments: Option, + /// Enable QP generation of fragments for subgraph requests /// Default: true pub(crate) generate_query_fragments: bool, @@ -739,6 +754,7 @@ impl Supergraph { introspection: Option, defer_support: Option, query_planning: Option, + reuse_query_fragments: Option, generate_query_fragments: Option, early_cancel: Option, experimental_log_on_broken_pipe: Option, @@ -749,6 +765,15 @@ impl Supergraph { introspection: introspection.unwrap_or_else(default_graphql_introspection), defer_support: defer_support.unwrap_or_else(default_defer_support), query_planning: query_planning.unwrap_or_default(), + reuse_query_fragments: generate_query_fragments.and_then(|v| + if v { + if reuse_query_fragments.is_some_and(|v| v) { + // warn the user that both are enabled and it's overridden + tracing::warn!("Both 'generate_query_fragments' and 'experimental_reuse_query_fragments' are explicitly enabled, 'experimental_reuse_query_fragments' will be overridden to false"); + } + Some(false) + } else { reuse_query_fragments } + ), generate_query_fragments: generate_query_fragments .unwrap_or_else(default_generate_query_fragments), early_cancel: early_cancel.unwrap_or_default(), @@ -767,6 +792,7 @@ impl Supergraph { introspection: Option, defer_support: Option, query_planning: Option, + reuse_query_fragments: Option, generate_query_fragments: Option, early_cancel: Option, experimental_log_on_broken_pipe: Option, @@ -777,6 +803,15 @@ impl Supergraph { introspection: introspection.unwrap_or_else(default_graphql_introspection), defer_support: defer_support.unwrap_or_else(default_defer_support), query_planning: query_planning.unwrap_or_default(), + reuse_query_fragments: generate_query_fragments.and_then(|v| + if v { + if reuse_query_fragments.is_some_and(|v| v) { + // warn the user that both are enabled and it's overridden + tracing::warn!("Both 'generate_query_fragments' and 'experimental_reuse_query_fragments' are explicitly enabled, 'experimental_reuse_query_fragments' will be overridden to false"); + } + Some(false) + } else { reuse_query_fragments } + ), generate_query_fragments: generate_query_fragments .unwrap_or_else(default_generate_query_fragments), early_cancel: early_cancel.unwrap_or_default(), diff --git a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap index e13580e514..7d75364612 100644 --- a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap +++ b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap @@ -6617,6 +6617,12 @@ snapshot_kind: text "description": "Log a message if the client closes the connection before the response is sent. Default: false.", "type": "boolean" }, + "experimental_reuse_query_fragments": { + "default": null, + "description": "Enable reuse of query fragments\n\nThis feature is deprecated and will be removed in next release. It is only available in JS QP. Use generate_query_fragments instead.", + "nullable": true, + "type": "boolean" + }, "generate_query_fragments": { "default": true, "description": "Enable QP generation of fragments for subgraph requests Default: true",