- Typed GraphQL Concrete Syntax Tree as per October 2021 specification
- Error resilience
- lexing and parsing does not fail or
panic
if a lexical or a syntax error is found
- lexing and parsing does not fail or
- GraphQL lexer
- GraphQL parser
Add the dependency to start using apollo-parser
:
cargo add apollo-parser
Or add this to your Cargo.toml
for a manual installation:
# Just an example, change to the necessary package version.
[dependencies]
apollo-parser = "0.8.3"
apollo-parser
is tested on the latest stable version of Rust.
Older version may or may not be compatible.
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 cst = 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 a CST (Concrete Syntax Tree), 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 cst = parser.parse();
// cst.errors() returns an iterator with the errors encountered during lexing and parsing
assert_eq!(0, cst.errors().len());
// cst.document() gets the Document, or root node, of the tree that you can
// start iterating on.
let doc = cst.document();
Two examples outlined here:
The examples directory in this repository has a few more useful implementations such as:
- using apollo-rs with miette to display error diagnostics
- using apollo-rs with annotate_snippets to display error diagnostics
- checking for unused variables
use apollo_parser::{cst, Parser};
let input = "
type ProductDimension {
size: String
weight: Float @tag(name: \"hi from inventory value type field\")
}
";
let parser = Parser::new(input);
let cst = parser.parse();
assert_eq!(0, cst.errors().len());
let doc = cst.document();
for def in doc.definitions() {
if let cst::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
}
}
}
use apollo_parser::{cst, Parser};
let input = "
query GraphQuery($graph_id: ID!, $variant: String) {
service(id: $graph_id) {
schema(tag: $variant) {
document
}
}
}
";
let parser = Parser::new(input);
let cst = parser.parse();
assert_eq!(0, cst.errors().len());
let doc = cst.document();
for def in doc.definitions() {
if let cst::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()]
);
}
}
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.