Skip to main content

Grafast v1 release candidate!

· 6 min read
Benjie
Inventor of Grafast
Jem
“I wear many hats”

The Grafast v1.0 release candidate is now available. The engine has stabilized, the epic milestones are complete, and the runtime has been hardened by more than a year of production use through PostGraphile V5 and standalone adopters. All that remains is to finish the documentation, tighten the TypeScript experience, and create more examples!

PostGraphile user? You may want to read the PostGraphile RC post instead.

What does release candidate mean for Grafast?

The runtime APIs, behaviour, and mental model have settled and the software has proven stable with some users having ran it in production for over a year; however, the documentation needs to catch up (and some TypeScript types and comments still need to be brought in line). The release candidate tag signals the stability of the software whilst leaving us the space to focus entirely on quality and documentation before stamping the final 1.0 release.

Now is the perfect moment to validate that the “plans as dataflow” approach clicks for you: do you understand the separation of “plan-time” and “execution-time”? Can you see how principled communication between the steps allows for optimization without needing to revisit plan resolvers?

If you don’t understand it, that’s likely a failing of our documentation! Help us improve our explanations by sharing your feedback (whether confusion and frustration or success and praise!) in our Discord or with GitHub issues and pull requests!

Documentation: where we need you

The code moved faster than the words that describe it. Parts of the docs are out of date, others are missing, and a few contradict the behaviour you see in practice. We need review, issue reports, and small patches. Your first-hand notes about what is unclear are invaluable. If something doesn’t behave according to the docs, or if the docs are unclear, let us know!

Feedback via GitHub issues or the Discord server is hugely appreciated.

From sketches and a dream to a stable execution engine

We came up with the initial seed for Grafast in 2020, having been frustrated by the limitations, caveats and inefficiencies of traditional resolver-driven GraphQL execution, along with the messiness and inefficiency of previous attempts to solve these problems (such as digging through GraphQLResolveInfo).

The building block we came up with, our north star, was the “plan resolver”: a function that looks deceptively similar to traditional resolvers, but changes the GraphQL resolution from procedural (field-by-field, layer-by-layer, with just-in-time discovery of data requirements leading to over-fetching, under-fetching, N+1 problems, and an explosion of promises) to declarative (holistic planning of the request, followed by optimal execution).

A comparison between a traditional resolver and a plan resolver. The plan resolver is about the same length and mirrors the shape of the traditional resolver, but the key difference is it describes how to get the data rather than actually fetching it.

Plan resolvers are a declarative replacement for traditional resolvers, they describe HOW to get the data rather than actually fetching it.

The various plan resolvers referenced by the operation would detail steps sufficient to satisfy their requirements, and these steps would be composed into an “operation plan” detailing the full requirements and data flows of the operation. This plan could then rewrite itself through principled communication between its constituent steps before being executed — the code that finally executes might no longer reflect the shape of the GraphQL request, leveraging advanced capabilities of the underlying business logic.

Working with the group

In 2023, we presented an early version of Grafast at GraphQLConf, and sought feedback from anyone who wished to get involved. Together, the Grafast working group identified four epics stood between this proof of concept and a stable 1.0:

  • Global dependencies: Grafast integrates batching as a core concept, but batching steps which would always have exactly one value in a request (such as field arguments, user credentials, API clients) was awkward. We now mark these as “unary” which makes them significantly easier to handle in custom steps.
  • Early exit: Grafast is about data flow, and branching should be handled inside business logic (i.e. inside step classes, not within plan resolvers). However, sometimes a plan resolver wants to “exit early” either with an error or a null, so these needs now have first-class support.
  • Plan-time evaluation removal: “peeking” at the value of inputs at plan time added “constraints” which limited the reusability of the plan. This “peeking” ($step.eval*()) has been removed from all public interfaces so today plan resolvers stay declarative; all decision making happens in step execution where it belongs, and there are far fewer constraints on when an operation plans can be reused leading to much less time spent planning.
  • Polymorphism convergence: previously, the operation plan would create a branch for each abstract type at each abstract position, leading to excessive planning time. This exponential branching hazard was eliminated by merging polymorphic branches back together before branching out for the next layer of abstract types.

We have also solidified the “thinking in plans” model: describe a simple dataflow for each field, let Grafast orchestrate its optimization, and reap the rewards of declarative execution in the form of reduced resource utilization, lower bills, and increased application performance.

Try Grafast v1 today

Install the release candidate from npm:

yarn add grafast

Start working your way through the documentation and let us know what still feels rough.

Sponsors make Grafast possible

Grafast exists thanks to the companies and individuals who fund our work. Their backing lets us spend the time needed to invent, iterate, and polish the engine you are using today. If Grafast helps you ship faster or operate more efficiently, please join them; find out more at graphile.org/sponsor.

Thank you