Skip to content
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

Query planning #3314

Open
IvanGoncharov opened this issue Oct 13, 2021 · 2 comments
Open

Query planning #3314

IvanGoncharov opened this issue Oct 13, 2021 · 2 comments

Comments

@IvanGoncharov
Copy link
Member

Problem

execute was designed as a simple implementation that follows GraphQL specification.
I think we should definitely for implementing anything that helps make it more usable in a typical graphql server.

However, there is growing demand to use execute in more complex tools/libraries to do stuff it wasn't designed to do (e.g. stitching, jit, etc.). Developers working on such libraries face a problem where they need to replace some parts of execute but don't want to support their own copy of execute.

One of the solutions is to convert the implementation of execute (as a class or separate function) into the framework with "hooks". It not only complicates code but also doesn't solve problems of libraries that want to do alternative execution concepts, for example, graphql-jit.

I want to propose an alternative solution that keeps execute as a simple library function but allows libraries to reuse the most complex parts and offer any "customization" they want to end-users.

It's sims that all other major implementations of GraphQL switched to query plans and are happy with it.
Having query plans have its drawbacks (it is slow and uses memory) but it's cachable and that mitigates them.
Yes, it's a big shot to implement this feature but it solves the core issue that we discussed recently.

Idea is to split execute into two parts:

  1. Generate a cachable query plan (with the query as a cache key) that has all possible things done ahead of execution (coercing args, collecting fields, preparing "static" part of the info object, etc.)
  2. Simple executor that executes query plan, since all work is done ahead of time it should be faster especially for cases where you have nested lists types in your query.

And #1 should solve the issue you have at the moment since even if you don't need all that data it's cachable so you can use only stuff that you need.
I expect all non-trivial libraries/tools (stitching, federation, graphql-jit) to replace #2 with custom code so idea is to make it as small as possible move as much stuff as possible into #1.

Query plans can also be used in other use cases, for example, you can implement client-side code generation as "reducing visitor" on the query plan.

@IvanGoncharov
Copy link
Member Author

We can run this plan as a separate experimentalExecutor folder meaning it doesn't touch production code (a way simpler review process, mostly about code style and general feedback) and it doesn't interfere with spec proposals like steam/defer.

Please note: This is not a trivial task so it should be worked by a person deeply familiar both with graphql and graphql-js internals. Also, the goal is to develop this feature in collaboration with one of the tools/libraries that experience problems that I mentioned in the above comment.

@IvanGoncharov
Copy link
Member Author

IvanGoncharov commented Oct 13, 2021

@yaacovCR This proposal is the result of the discussion we had, it also related to the issues and PRs you opened recently.
Would be great to hear your opinion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant