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.
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
Signature normalization, ordering fragments #2282
Signature normalization, ordering fragments #2282
Changes from 4 commits
6f3313e
a494e94
ec695b9
24dcd99
1b70cd3
d1aeb3a
2ad998b
602eb66
077e2c7
d341e08
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
These tests are invaluable. Thank you so much for adding these!
I suspect we would see additional value (now or in the future) in a test which had multiple named operations in it. The spec states that if there is a single operation in a document, it need not be named, however if there are 2 or more, each must be named. I think it would be smart of us to try to incorporate tests which test that sorting behavior. Would that be something you'd entertain adding?
Currently, if a document contains multiple operations, the name of the operation for which single execution is desired should be passed in. The graphql/graphql-spec#375 RFC proposes another plan for the future, if you're interested.
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 very helpful articulation of some behavior I was seeing during further implementation today.
I'll gladly add some tests specific to what you've mentioned (if I haven't already - will go back and take a look). I went a little crazy adding tests since I found TDD to be the fastest and best way to implement these changes :woo:!
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.
Hmm, I think we should avoid doing direct filtering passes on the AST to account for
Node
s (likeFragmentDefinitionNode
s) which may not exist.Also, while the typing of this
sortAST
function currently accepts aDocumentNode
(right now), it should theoretically be able to handle sub-ASTs as well (GraphQL'svisit
can actually handle more than justDocumentNode
), if we ever desired to do so.I think remaining aligned with the original behavior of this
sortAST
to be a direct implementation of a visitor may be still possible.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.
Yes, totally agree! Are you recommending changes for the input type (
DocumentNode
) or just pointing out that we may be able to make this more flexible in the future?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.
Visitor comment resolved in d341e08.
Leaving this thread open for question above.
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 fear that this is overly specific. Given the definition of
DefinitionNode
andExecutableDefinitionNode
:I don't know what
TypeSystemDefinitionNode
orTypeSystemExtensionNode
are, but they are legal values in aDefinitionNode
. This also would be susceptible to be other new things added in the future. With that lack of knowledge, I think it would make sense to favor using "fragments and everything else" versus "fragments and operations". Thoughts?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'm operating under the assumption that the document will only have
ExecutableDefinitionNodes
else it wouldn't be a valid operation signature. I wouldn't expect the other twoTypeSystemXNode
s to turn up in an operation (they're used in SDL) but that may be an incorrect assumption.Regardless of what I find, I'll add some documentation here to explain.
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.
That is totally true for our use case. I don't think you can be positive that it covers all use cases for both us and consumers of
apollo-graphql
.The function is called
sortAST
and accepts aDocumentNode
; I think you need to account for all legal values that might exist in aDocumentNode
.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.
Left a piece off the above comment: this function is called
sortAST
; so it might be used to sort any kid of AST. Restricting this toDocumentNode
s that only includeExecutableDefinitionNodes
doesn't feel right.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 think giving this a more specific name, like
lexicographicSortOperations
(by analogy withlexicographicSortSchema
might be more appropriate.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.
Filtering out non-
ExecutableDefinitionNode
s (as you currently do) might be ok, that is also whatexecute
does. Alternatively, maybe we could put them all at the end?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 support a different name! But I'm pretty okay with not exposing
sortAST
as a public API, instead only exposing abstractions that implement it (likedefaultEngineReportingSignature
in the adjacentindex.ts
)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.
Resolved in 2ad998b
Following @martijnwalraven 's suggestion of parity with the graphql function, I've opted to rename (and effectively repurpose) this:
lexicographicSortOperations
.This is worth discussing - it's a breaking change but this package is new and may not be in use. Regardless, this requires a major version bump.
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.
@abernix I'm just now seeing your comments as I had a stale page up while responding to comments. I'm open to not exporting this function publicly.
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 believe that in order to achieve a more reliable normalized signature, we should first sort the
definitions
on aDocumentNode
by theirkind
property, in a similar way to how we sortSelectionSet
selections
: first bykind
, thenname.value
. This would placeFragmentNodes
aboveDocumentNodes
consistently.I believe the only
Node
without a name at that level should be anOperationNode
in which it's optional, except for when there are multipleOperationNode
s.I tried to quickly piece together what I thought the sorting would be like in the most complex situation, and I think it'd be:
It's worth noting that since we're only concerned with executable operations, based on current server implementations in which the presence of most of those
Node
types would cause a validation error, I think the only sorting we'll end up with that matters is a fraction of those Nodes.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.
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 excellent. See: d341e08
I'd like your take on the iteratees that I've added.
operation
will give a nice grouping ofquery
mutation
subscription
. I don't see this adding any value to the normalization itself, but I imagine it will read much more nicely. Do we expect human eyes on these at any point? I don't know the answer to that.