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.
Fixes #5011
The spec says that JSON key-value pairs should come back in the same order that they were requested in the query. I need an implementation that complies with the spec and adds as little overhead as possible (memory and runtime). Possibly, if it adds noticeable overhead, make it opt-in, since this is critical performance code
I need to somehow maintain the sequence of this result even when Dataloader or GraphQL-Batch write to it out of order (see #4252).
I think the
selections_by_name
hash(es) have the correct order of keys here:graphql-ruby/lib/graphql/execution/interpreter/runtime.rb
Lines 120 to 192 in d9bd9cf
I can't find any way to re-order a Ruby Hash. So if I'm going to use a Hash, need to write the keys in the right order the first time. (Technically, you can move a key to the back by doing
h[k] = h.delete(k)
, but I don't think that's a promising approach.)Another approach might be to use an Array to hold values and then build a Hash from there. For example, an array of
[k1, v1, k2, v2, ...]
could be used. One problem here is that it will require a second pass through the whole data structure. GraphQL-Ruby used to do this, but it was slow. I'd like to not make it do that again.Maybe I could mitigate the downside of the second iteration by implementing
Result#to_json
to return a properly-ordered string. This would work out-of-the-box with Rails... but I know a lot of JSON serializers are really optimized. Could GraphQL-Ruby deliver good performance in that case? (And if I take that approach, I should implement.to_ordered_h
and test it against.to_ordered_h.to_json
with an optimized JSON serializer.)graphql-js
handles this by writing promises into the result hash. This is also how GraphQL-Ruby happens to handleGraphQL::Execution::Lazy
instances (eg, GraphQL-Batch). Perhaps a similar approach can be made to work with Dataloader. But the challenge is cleaning up those placeholders. APromise
has its owncatch
block to do that, but Dataloader doesn't have that... (yet?)