graphql-parser

module
v0.0.0-...-6ed2364 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 1, 2026 License: MIT

README

graphql-parser

A small, dependency-free Go library that parses GraphQL source text into an AST. Supports both grammars from the October 2021 GraphQL spec — executable documents and the type-system / SDL — in three small packages:

github.com/brian-bell/graphql-parser/ast    // node types, Source, Position, Loc, Walk
github.com/brian-bell/graphql-parser/lexer  // tokenizer
github.com/brian-bell/graphql-parser/parser // Parse, ParseSource, ParseValue, ParseConstValue, ParseType

Validation, execution, and printing are out of scope.

Install

go get github.com/brian-bell/graphql-parser

Requires Go 1.26+.

Usage

Parse a document
import "github.com/brian-bell/graphql-parser/parser"

doc, err := parser.Parse(`
    query GetUser($id: ID!) {
        user(id: $id) { id name email }
    }
`)
if err != nil { panic(err) }

for _, def := range doc.Definitions {
    // type-switch on def: *ast.OperationDefinition, *ast.FragmentDefinition,
    // *ast.ObjectTypeDefinition, etc.
}
Parse a single value or type literal
v, err := parser.ParseValue(`{ id: 1, tags: ["a", "b"] }`)
t, err := parser.ParseType(`[String!]!`)

ParseConstValue is the const-context variant; it rejects $variables at any nesting depth. Use it for default-value parsing.

Position-rich errors

Errors include a graphql-js-style source-line snippet with a caret pointer:

Syntax Error: Expected Name, found <EOF>.

example.graphql:3:1
2 |   field(
3 | }
  | ^

Reported line/column numbers honor Source.LocationOffset, so errors in a fragment parsed from a larger file (e.g. an embedded gql template tag) report the original file's coordinates.

Walking the AST

ast.Walk and ast.Inspect traverse a node depth-first in source order:

import "github.com/brian-bell/graphql-parser/ast"

ast.Inspect(doc, func(n ast.Node) bool {
    if f, ok := n.(*ast.Field); ok {
        fmt.Println(f.Name)
    }
    return true // continue descending
})

Options

Every Parse* entry point accepts variadic options.

WithRecovery

Collect multiple syntax errors instead of aborting on the first.

doc, err := parser.Parse(brokenSource, parser.WithRecovery())
if err != nil {
    var es parser.ParseErrors
    if errors.As(err, &es) {
        for _, pe := range es {
            fmt.Println(pe)
        }
    }
}

The returned document is still populated with whatever could be parsed; the parser inserts BadDefinition and BadField placeholder nodes where it had to resynchronize. This is what an LSP wants when the user is mid-typing.

WithComments

Attach # ... line comments as Leading trivia on AST nodes (top-level Definitions, FieldDefinitions, EnumValueDefinitions, InputValueDefinitions).

doc, _ := parser.Parse(source, parser.WithComments())
def := doc.Definitions[0].(*ast.ObjectTypeDefinition)
for _, c := range def.Comments.Leading {
    fmt.Println(c.Text)
}

When this option is not set, the parser silently skips comments and the AST is byte-identical to the no-comments configuration.

Why this library?

There are existing Go GraphQL parsers (gqlparser, graphql-go/graphql), and they're fine for most use cases. This library targets the gap they leave for tooling consumers:

  • Full-extent positions. Every *ast.Loc carries {Start, End} byte offsets covering the entire node, not just its first token. Formatters, LSPs, linters, and renamers all want this.
  • Idiomatic Go AST. Interfaces at spec union points (Definition, Selection, Value, Type); concrete pointer-receiver structs everywhere else. No kind discriminator, no nil-load-bearing fields.
  • Recovery + comments built-in. Both are opt-in (off by default to preserve fail-fast and corpus conformance) but there's no extra package to import or library to wrap.

Conformance is held to a simple bar: in default fail-fast mode, the parser passes the ported graphql-js parser test corpus byte-for-byte on error messages.

License

MIT — see LICENSE. The ported test corpus under parser/testdata/graphql-js/ carries the upstream graphql-js MIT license; see THIRD_PARTY_LICENSES.md.

Directories

Path Synopsis
Package ast defines the GraphQL abstract syntax tree, including node types, source-position tracking, and traversal helpers.
Package ast defines the GraphQL abstract syntax tree, including node types, source-position tracking, and traversal helpers.
Package lexer tokenizes a GraphQL source document.
Package lexer tokenizes a GraphQL source document.
Package parser converts GraphQL source text into an ast.Document (or, via partial entry points, a single ast.Value or ast.Type).
Package parser converts GraphQL source text into an ast.Document (or, via partial entry points, a single ast.Value or ast.Type).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL