-
Notifications
You must be signed in to change notification settings - Fork 55
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
Fix: fully traverse nested field selections while planning #85
Conversation
a0c3b28
to
d7f0404
Compare
Codecov Report
@@ Coverage Diff @@
## main #85 +/- ##
==========================================
+ Coverage 67.01% 67.11% +0.09%
==========================================
Files 24 24
Lines 2747 2749 +2
==========================================
+ Hits 1841 1845 +4
+ Misses 750 749 -1
+ Partials 156 155 -1
Continue to review full report at Codecov.
|
c79fb28
to
f6faa3f
Compare
f6faa3f
to
937ba59
Compare
"ServiceURL": "A", | ||
"ParentType": "Movie", | ||
"SelectionSet": "{ _id: id title }", | ||
"InsertionPoint": ["movies", "compTitles"], | ||
"InsertionPoint": ["movies", "compTitles", "compTitles"], |
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.
The order of steps changed here because the extractSteps
call moved lower in the extractSelectionSet
process. However, this reordering of steps should be benign to the execution process.
} | ||
if loc != location { | ||
// field transitions to another service location | ||
remoteSelections = append(remoteSelections, 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 the only actual change to this conditional: transitions in service location now collect remote fields into an array and resolve them all at once later in the process, versus resolving each remote field individually here. There's a lot less churn resolving them together, and it avoids the situation that mergedWithExistingStep
was previously trying to address.
The else if
and else
blocks are identical to their previous implementations, they're simply indented out now that the conditional structure can be flattened.
@gmac You've potentially already figured it out but this is due to this line https://github.com/movio/bramble/blob/main/plan.go#L228, as the iteration ordering over maps is intentionally random in golang. Sorting the output feels wrong because we don't actually care about ordering other than for the test. At the same time due to the fact the selection set is a string here makes it a difficult to fix comparison. It might pay to create something custom for that test. If we can parse the selection set string back into the AST format we could simply check for the presence of each fragment. |
Good call! Yep, I learned this morning about randomized map orders... it was a surprise to me coming from the land of Ruby and JS where enumerable keys maintain definition order. Thanks for the info and the tip. Will have another PR for that fix in the next day or two. |
@gmac Great find, looks good from my perspective. The fix and added tests make sense, I think the collect and then create approach is cleaner too. |
As described in #73, deeply-nested selection paths that transitioned between services were broken. This was a fairly significant issue.
The problem
While extracting selection sets, the
mergedWithExistingStep
check was treating all consolidated fields as leaf values. That means that when a composite field was encountered with its own nested selections, that entire selection set was merged into the current planning step without traversing its children to delegate them properly. This resulted in fields belonging to foreign services getting lumped into the present service selection, and the query failing with a GraphQL validation message:The fix
This adjusts the flow of
extractSelectionSet
so that all remote fields are collected up front and then create steps once together later in the process. This eliminates the need for the previous step-merging pattern, and is computationally simpler to create steps all at once rather than creating them incrementally for each remote step in sequence.Note that this refactor looks bigger than it really is: this simplification was able to remove some conditional nesting and thus decrease the indent on a few existing code blocks.
Tests
Tests have been added. There's one update to an existing test where a benign array order has changed due to the revised sequencing of extracting remote fields.
Resolves #73.