Expand description

apollo-parser

A parser for the GraphQL language.

Crates.io version Download docs.rs docs

Features

  • Typed GraphQL AST as per October 2021 specification
  • Error resilience
    • lexing and parsing does not fail or panic if a lexical or a syntax error is found
  • GraphQL lexer
  • GraphQL parser

Getting started

Add this to your Cargo.toml to start using apollo-parser:

[dependencies]
apollo-parser = "0.2.4"

Or using cargo-edit:

cargo add apollo-parser

Usage

apollo-parser is built to parse both GraphQL schemas and queries according to the latest October 2021 specification. It produces a typed syntax tree that then can be walked, extracting all the necessary information. You can quick start with:

use apollo_parser::Parser;

let input = "union SearchResult = Photo | Person | Cat | Dog";
let parser = Parser::new(input);
let ast = parser.parse();

apollo-parser is built to be error-resilient. This means we don’t abort parsing (or lexing) if an error occurs. That means parser.parse() will always produce an AST, and it will be accompanied by any errors that are encountered:

use apollo_parser::Parser;

let input = "union SearchResult = Photo | Person | Cat | Dog";
let parser = Parser::new(input);
let ast = parser.parse();

// ast.errors() returns an iterator with the errors encountered during lexing and parsing
assert_eq!(0, ast.errors().len());

// ast.document() gets the Document, or root node, of the tree that you can
// start iterating on.
let doc = ast.document();

Examples

Two examples outlined here:

The examples directory in this repository has a few more useful implementations such as:

Get field names in an object
use apollo_parser::{ast, Parser};

let input = "
type ProductDimension {
  size: String
  weight: Float @tag(name: \"hi from inventory value type field\")
}
";
let parser = Parser::new(input);
let ast = parser.parse();
assert_eq!(0, ast.errors().len());

let doc = ast.document();

for def in doc.definitions() {
    if let ast::Definition::ObjectTypeDefinition(object_type) = def {
        assert_eq!(object_type.name().unwrap().text(), "ProductDimension");
        for field_def in object_type.fields_definition().unwrap().field_definitions() {
            println!("{}", field_def.name().unwrap().text()); // size weight
        }
    }
}
Get variables used in a query
use apollo_parser::{ast, Parser};

let input = "
  query GraphQuery($graph_id: ID!, $variant: String) {
    service(id: $graph_id) {
      schema(tag: $variant) {
        document
      }
    }
  }
  ";

  let parser = Parser::new(input);
  let ast = parser.parse();
  assert_eq!(0, ast.errors().len());

  let doc = ast.document();

  for def in doc.definitions() {
      if let ast::Definition::OperationDefinition(op_def) = def {
          assert_eq!(op_def.name().unwrap().text(), "GraphQuery");

          let variable_defs = op_def.variable_definitions();
          let variables: Vec<String> = variable_defs
              .iter()
              .map(|v| v.variable_definitions())
              .flatten()
              .filter_map(|v| Some(v.variable()?.text().to_string()))
              .collect();
          assert_eq!(
              variables.as_slice(),
              ["graph_id".to_string(), "variant".to_string()]
          );
      }
  }

License

Licensed under either of

  • Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)

at your option.

Modules

Typed AST module to access nodes in the tree.

Macros

Create a new SyntaxKind.

Create a new TokenKind.

Structs

An Error type for operations performed in the lexer and the parser.

Parses tokens into text.

Parse GraphQL schemas or queries into a typed AST.

An AST generated by the parser. Consists of a syntax tree and a Vec<Error> if any.

A token generated by the lexer.

Enums

Tokens generated by the lexer.