-
Notifications
You must be signed in to change notification settings - Fork 326
Stop relying on apply_selection_set for connectors GraphQL response mapping
#8178
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
Conversation
✅ Docs preview has no changesThe preview was not built because there were no changes. Build ID: f194957f134fc66b3a668576 |
a7d8dc6 to
542122e
Compare
apply_selection_set for connectors GraphQL response mappingapply_selection_set for connectors GraphQL response mapping
eef1acc to
43f056a
Compare
|
Does this also impact the response caching stuff that @lennyburdette is working on? Or is that keyed on operation? Would be cool if |
2a35586 to
756e131
Compare
|
@benjamn, please consider creating a changeset entry in |
|
@dylan-apollo Not sure about the exact cache key inputs (curious to hear from @lennyburdette), but this PR should in principle reduce the total number of distinct JSONSelections produced by |
0c91f46 to
d355501
Compare
a001d9d to
eada1f5
Compare
fe2b18b to
edbc5cc
Compare
apollo-federation/src/connectors/json_selection/selection_set.rs
Outdated
Show resolved
Hide resolved
edbc5cc to
a22b42f
Compare
Note
This PR targets the branch for #8073, which is a preview release branch for
connect/v0.3-associated features. This PR's branch is targeted in turn by #8143.While a single JSONSelection string (e.g. the
selectionargument to a@connectdirective) represents everything a particular HTTP endpoint might return, in most cases individual GraphQL operations (especially those generated by the query planner) will ask for fewer fields, and may alias/rename those fields.Historically (since PR #5635), we've used
apply_selection_setinjson_selection/selection_set.rsto transform the full JSONSelection into whatever a given operation asks for, including implementing field aliasing within the transformed JSONSelection string. In theory, this selection filtering/transforming should make selection execution less expensive at runtime, but we never implemented transform caching, so the transform was happening for every incoming operation at runtime, probably not improving performance overall.More importantly, with the advent of abstract types, conditional selections, and more complicated use of
->methods (where changing something about the output would require rewriting input arguments), it is no longer generally possible to accomplish everything we want by transforming the JSONSelection. This limitation became apparent recently when a field that came from within a->matchmethod was renamed with an alias in the GraphQL query. The renamed field ended upnullbecause the field was not actually renamed in the JSONSelection, becauseapply_selection_setdoes not descend into rewriting->method arguments.Instead, this PR implements a foolproof backup plan: instead of relying on
apply_selection_setalone, we execute incoming GraphQL operations against the JSONSelection mapping results, using knowledge of fragments, aliases, and supertype-subtype relationships from the schema. This meansapply_selection_setis no longer responsible for any alias renaming, since all of that is handled later. However,apply_selection_setis still responsible for pruning as much of the JSONSelection as possible, when there are fields we can statically detect are definitely unused.Another approach here would be to make the
JSONSelection::apply_to_pathmethod take anExecutableDocumentand only execute fields that are needed by the operation, so we wouldn't have to transform the selection, but that's an optimization that adds complexity, compared to this PR.