Refactor Fields into FieldSelection to be more flexible #2794
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This was a journey and hopefully this PR description and the new code better describes the actual use cases and when to use the available functionality.
Bug fix: Excluding fields from types that are actually relevant
Previously with
Fields
I was limiting the types to filter out any irrelevant types. I do not know why I was doing this, because GQL already enforces that irrelevant types are not spread into a field selection. It turns out I was limiting the types too much, and breaking some use cases.Like this one
If the report was a
ProgressReport
, theparent
was declared as aLanguageEngagement
.So the previous logic took that field type, and mistakenly didn't consider the interfaces of
LanguageEngagement
becauseLanguageEngagement
was NOT an interface.Thus the request for
project
was ignored and the ID shortcut was used.Which then broke the resolver for project who was expecting an
Engagement
but only had the ID shortcut.So I went about fixing that mistake so that interfaces of concrete object types were included. And then I thought about unions as well.
And then I asked myself, "what am I actually excluding here?"
I found out that Apollo Server already enforces that fragments cannot be spread into places where there is no correlation.
So in reality, we should've been considering all the fields from all the types, as they could've been applicable.
The logical change, and bug fix, in this PR is to stop filtering out fields for types because they could be relevant. Like how the
Engagement
type is used in the example above.New Features
The next question I asked myself is "why does
simplifyParsedResolveInfoFragmentWithType
fromgraphql-parse-resolve-info
(the underlying library providing this functionality) exist?"Which was the previous "filter" logic I had adapted and now just removed.
Well, I found it out it is because if we did have better information, we could want to limit the selected fields more.
Take this example:
Here we are asking for
language
ormentor
based on the type of Engagement returned. Since the query returns the interfaceEngagement
, GQL knows it could be either concrete type.Say, for example, we determined the type of the engagement for the given ID was actually a
LanguageEngagement
.It would be appropriate in that case to ignore the
mentor
field selection as we know Apollo Server will do the same.With this new
FieldSelection
class I added functionality for that.It's a bit contrived I know. Say
language
wasn't selected, and we knew we had aLanguageEngagement
and we could ignore thementor
field.Since only the id was requested, and we have it, and we know we can ignore
mentor
then we do not need to go to the DB.┆Issue is synchronized with this Monday item by Unito