You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been spending a lot of time trying to move the existing execution code forward in a compatible way, but I'm finding it impossible :S I mean at least these modules:GraphQL::Execution::Interpreter, Interpreter::Runtime, Interpreter::Arguments (and HasArguments, ArgumentValue), Dataloader, Execution::Lazy.
Writing up all the details is possible but in the interest of getting started, I'll be brief:
Correctness: GraphQL-Ruby has received a lot of features over the years, tacked on in different ways. They don't always work right together... it's worth considering which ones can be jettisoned for other approaches (field extras?) or merged together, at least under the hood (prepare:, loads:, validates:?).
Features: actually, performance is the feature that I'd want from this. I expect most features could be reimplemented one way or another -- or at least a very clear migration path -- with a new core runtime.
So, I'm proposing a project like:
Build a new runtime in isolation (takes the same inputs as Schema.run, returns the same output; can be used on a query-by-query basis for Scientist-like checks)
Make sure the new runtime checks the necessary boxes (see below)
One at a time, reimplement existing features to the degree possible
Also build a "GraphQL Doctor" which inspects source code and schemas in memory and outputs the result of compatibility checks and links to migration notes
After trying and trying, I don't think a future execution paradigm can be achieved with a perfectly smooth path, but I think it's worth pursing -- Shopify has been using custom execution code to great success for a while now.
New Execution Goals in no specific order:
Support first-class batching ("batch resolvers"), so you can get the advantages of dataloader or graphql-batch without promises or fibers, using a breadth-first execution algorithm (Supporting Batch Resolvers in GraphQL-Ruby #5446)
cc @gmac since you've been investigating a lot of these too -- what do you think this approach to improving GraphQL-Ruby?
Appendix: essential and non-essential forwards-compatible features
These are things that must have good enough compatibility that a given application can switch between runtimes on a query-by-query basis:
Everything in the GraphQL spec (including null propagation, @skip/@include, static validation (same code))
Query analyzers (same code used in both cases)
Custom scalars
Resolver classes
Dataloader
GraphQL-Batch support
Schema visibility (same code should work in this new runtime, since it's applied during static validation)
Multiplex: I expect this to basically work fine in the new flow with a bit of work.
Connections
Argument #authorized?
Field #authorized?
Type .authorized? and .scope_items
Tracing
loads:
validates:
prepare:
Resolver#ready?
field extras:
A few are already implemented; others could be if requested.
field extensions:
Requires implementing new methods
Custom context and query classes just works
Then there are some features whose forward compatibility I don't consider to be essential. In these cases, supporting both runtimes in your schema might require de-customizing (ie, moving behavior into your app code or into a resolver). However I bet they'll eventually be able to be reimplemented in a very compatible way, and I expect them to be easily identifiable by "GraphQL Doctor":
It turns out everything on this list can stay compatible with minimal overhead.
GraphQL::Schema::Object .wrap(...) is not called anymore.
I have been spending a lot of time trying to move the existing execution code forward in a compatible way, but I'm finding it impossible :S I mean at least these modules:
GraphQL::Execution::Interpreter,Interpreter::Runtime,Interpreter::Arguments(andHasArguments,ArgumentValue),Dataloader,Execution::Lazy.Writing up all the details is possible but in the interest of getting started, I'll be brief:
lazy?#4426) but are stuck in compatibility land for edge casesextras?) or merged together, at least under the hood (prepare:,loads:,validates:?).So, I'm proposing a project like:
Schema.run, returns the same output; can be used on a query-by-query basis for Scientist-like checks)After trying and trying, I don't think a future execution paradigm can be achieved with a perfectly smooth path, but I think it's worth pursing -- Shopify has been using custom execution code to great success for a while now.
New Execution Goals in no specific order:
cc @gmac since you've been investigating a lot of these too -- what do you think this approach to improving GraphQL-Ruby?
Appendix: essential and non-essential forwards-compatible features
These are things that must have good enough compatibility that a given application can switch between runtimes on a query-by-query basis:
@skip/@include, static validation (same code))#authorized?#authorized?.authorized?and.scope_itemsloads:validates:prepare:Resolver#ready?extras:extensions:Then there are some features whose forward compatibility I don't consider to be essential. In these cases, supporting both runtimes in your schema might require de-customizing (ie, moving behavior into your app code or into a resolver). However I bet they'll eventually be able to be reimplemented in a very compatible way, and I expect them to be easily identifiable by "GraphQL Doctor":It turns out everything on this list can stay compatible with minimal overhead.
.wrap(...)is not called anymore.