Skip to content

Instantly share code, notes, and snippets.

@bruce
Last active November 2, 2019 16:03
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bruce/fb1b17b4fff4ce14c6af7510fe074a5e to your computer and use it in GitHub Desktop.
Save bruce/fb1b17b4fff4ce14c6af7510fe074a5e to your computer and use it in GitHub Desktop.
Very brief description of how Absinthe processes GraphQL

GraphQL document is parsed:

This returns a tree of Absinthe.Language nodes (structs), effectively the AST:

This tree is converted to a tree of Absinthe.Blueprint nodes (structs):

(At the moment the Language and Blueprint trees are separate; in the future we may decide to combine them, but the separation makes certain things easier to reason about).

The Blueprint tree is processed through a "pipeline" of phases (in fact, the parsing/creation of the trees(s) were the first steps in the pipeline):

Our phases are much more discrete than classic GraphQL Parsing, Validation, Execution phases; there are about ~40 phases for processing documents; each phase takes an input and returns an output for the next phase. Post-parsing this means the Blueprint tree is passed in, and an annotated/modified Blueprint tree is returned from each phase.

In our current master/unstable release, schema compilation is handled via a Blueprint tree as well; rather than harvesting results from the tree as with GraphQL documents, intermediate Blueprint trees modeling the schema definition are created using either Elixir macros or SDL input, then passed through to a phase that emits an optimized module (our schemas) for compilation (by Elixir/BEAM).

Inserting phases into the currently executing pipeline, jumping to the end, etc, are how we handle validation and execution errors, re-running for batch execution, etc.

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