Skip to content

Query planning #3314

Open
Open
@IvanGoncharov

Description

@IvanGoncharov

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions