26 releases
new 0.6.2 | Sep 19, 2023 |
---|---|
0.5.3 | May 12, 2023 |
0.5.0 | Feb 17, 2023 |
0.4.1 | Dec 13, 2022 |
0.1.0 | Nov 24, 2021 |
#55 in Parser implementations
15,469 downloads per month
Used in 9 crates
(6 directly)
290KB
8K
SLoC
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
- lexing and parsing does not fail or
- GraphQL lexer
- GraphQL parser
Getting started
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.6.2"
Rust versions
apollo-parser
is tested on the latest stable version of Rust.
Older version may or may not be compatible.
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:
- using apollo-rs with miette to display error diagnostics
- using apollo-rs with annotate_snippets to display error diagnostics
- checking for unused variables
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.
Dependencies
~1.2–1.9MB
~37K SLoC