-
Notifications
You must be signed in to change notification settings - Fork 493
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
Added possibility to explore the actual field selection tree #422
base: master
Are you sure you want to change the base?
Conversation
Each resolver's context will now be able to access through the graph of elements that were selected as part of the execution of this resolve via the standard go context's value. The returned field is an interface representing a subset of the functionality of the internal/exec/selected package, enough for the developer to know what was queried by the user. I'm opening the PR to start a discussion about offering this feature to end user of the library. We have started using it in our own fork of the library. ##### Design This introduces new API interfaces the would become part of the standard library. The interface is currently a simple wrapper around elements of `internal/exec/selected/Selection` interface needed to "walk" the selected field. Hopefully, I got the structure right. I've currently used `Identifier()` instead of `Name()` and `Aliased()` instead of `Alias` to not renamed the field's name since there would be conflict with struct fields in the `internal/exec/selected/Selection` package. If we agree, the internal struct could change so the interface has the best name. A future addition that I forsee could be: - A "path" retrieval syntax "a la" gjson to quickly extract some nodes of the selection, for example with the star wars element ".search[]" that would return all type assertion nodes below the `search` field. Exact semantic to be discussed. - Maybe a visitor pattern to ease the walking of the selection tree.
Field selected.Field | ||
} | ||
|
||
// GraphQLContext is used to retrieved the graphql from the context. If no graphql |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong comment
@@ -4,12 +4,14 @@ | |||
package starwars | |||
|
|||
import ( | |||
"context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes here are just for demonstration purposes if someone wants to play with the feature a bit. To try it out, run the starwars example server and perform this curl
call:
curl 'http://localhost:8080/query' -d '{"query":"query {search(text:\"C-3PO\") {... on Droid {name} ... on Starship {name}}}","variables":null}'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not intend to ship that if the feature is merged, it will be removed.
Aliased() string | ||
} | ||
|
||
func Dump(selection Selection) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also present mainly for debugging/exploration purposes, another method that could be removed.
The use case we have right now is to explore the type assertion provided by the user, like in the starwars search query:
We use the elements as a "filter" in our backend so we do not search for everything, only for what was requested by the user. |
return selected.FieldKind | ||
} | ||
|
||
func (f *SchemaField) Identifier() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't use Name()
method here yet since the backing internal/exec/selected/*SchemaField
already has a field Name
so it conflicts.
At one point, if we all agree on the feature and the interface, I suggest the internal field changes to the interface looks better.
This is the same reasoning for Aliased
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't you use its own Name
field then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the new public interface would exposes it, hence a field with the same name cannot exist.
Added possibility to explore the actual field selection tree, this is attached to the context that the resolver method receive. I'm opening this to gather feedback about this new feature.
Each resolver's context will now be able to access through the graph of elements that were selected as part of the execution of this resolve via the standard go context's value.
The returned field is an interface representing a subset of the functionality of the internal/exec/selected package, enough for the developer to know what was queried by the user.
I'm opening the PR to start a discussion about offering this feature to end user of the library. We have started using it in our own fork of the library.
Design
This introduces new API interfaces the would become part of the standard library.
The interface is currently a simple wrapper around elements of
internal/exec/selected/Selection
interface needed to "walk" the selected field. Hopefully, I got the structure right.I've currently used
Identifier()
instead ofName()
andAliased()
instead ofAlias
to not renamed the field's name since there would be conflict with struct fields in theinternal/exec/selected/Selection
package. If we agree, the internal struct could change so the interface has the best name.A future addition that I forsee could be:
search
field. Exact semantic to be discussed.