Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable generate_query_fragments by default #6013

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### Enable query fragment generation by default

The router previously had `experimental_reuse_query_fragments` enabled by
default when trying to optimize fragments before sending operations to subgraphs.
While on occasion this algorithm can be more performant, we found that in vast
majority of cases the query planner can be just as performant using
`generate_query_fragments` query plan option, which also significantly reduces
query size being sent to subgraphs. While the two options will produce correct
responses, the queries produced internally by the query planner will differ.

This change enables `generate_query_fragments` by default, while disabling
`experimental_reuse_query_fragments`. You can change this behavior with the
following options:

```yaml
supergraph:
generate_query_fragments: false
experimental_reuse_query_fragments: true
```

By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013
7 changes: 6 additions & 1 deletion apollo-router/src/configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,8 @@ pub(crate) struct Supergraph {
pub(crate) reuse_query_fragments: Option<bool>,

/// Enable QP generation of fragments for subgraph requests
/// Default: false
/// Default: true
#[serde(default = "default_generate_query_fragments")]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fails our own default tests:

Screenshot 2024-09-17 at 14 59 07

The only way for this config to have its own Default implementation is to be defined as an enum/struct, which feels wayyy too much for something like this. Any other ideas on setting up a default in a single place for this config?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove #[serde(default = "default_generate_query_fragments")] and replace two instances of generate_query_fragments.unwrap_or_default() in this file with generate_query_fragments.unwrap_or_else(default_generate_query_fragments)

Since the struct already has #[serde(default)] serde will rely on the existing impl Default for Supergraph

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i felt that using unwrap_or_else hid away the default definition. but i guess since we've got a doc comment with Default: true it's maybe a bit more clear.

pub(crate) generate_query_fragments: bool,

/// Set to false to disable defer support
Expand All @@ -710,6 +711,10 @@ pub(crate) struct Supergraph {
pub(crate) experimental_log_on_broken_pipe: bool,
}

const fn default_generate_query_fragments() -> bool {
true
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case", untagged)]
pub(crate) enum AvailableParallelism {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6557,8 +6557,8 @@ expression: "&schema"
"type": "boolean"
},
"generate_query_fragments": {
"default": false,
"description": "Enable QP generation of fragments for subgraph requests Default: false",
"default": true,
"description": "Enable QP generation of fragments for subgraph requests Default: true",
"type": "boolean"
},
"introspection": {
Expand Down
17 changes: 13 additions & 4 deletions docs/source/configuration/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1175,18 +1175,27 @@ example:

### Fragment reuse and generation

By default, the router will attempt to reuse fragments from the original query while forming subgraph requests. This behavior can be disabled by setting the option to `false`:
By default, the router will _generate_ fragments for subgraph requests,
extracting _inline fragments only_ into fragment definitions before sending
queries to subgraphs. In very many cases this significantly reduces the size of
the query sent to subgraphs, but may increase the time it takes for planning.
Note that this option and `experimental_reuse_query_fragments` are mutually
exclusive; if both are explicitly set to `true`, `generate_query_fragments` will
take precedence. This behaviour can be disabled by setting the option to `false`:
lrlna marked this conversation as resolved.
Show resolved Hide resolved

```yaml
supergraph:
experimental_reuse_query_fragments: false
generate_query_fragments: false
```

Alternatively, the router can be configured to _generate_ fragments for subgraph requests. When set to `true`, the router will extract _inline fragments only_ into fragment definitions before sending queries to subgraphs. This can significantly reduce the size of the query sent to subgraphs, but may increase the time it takes for planning. Note that this option and `experimental_reuse_query_fragments` are mutually exclusive; if both are explicitly set to `true`, `generate_query_fragments` will take precedence.
Alternatively, the router can attempt to reuse fragments from the original query
while forming subgraph requests. This often results in largers queries sent to
subgraphs, but it may be decrease planning times. This behavior can be enabled
by setting the option to `true`:

```yaml
supergraph:
generate_query_fragments: true
experimental_reuse_query_fragments: true
```

### Reusing configuration
Expand Down
Loading