apollo-parser
Add the dependency to start using apollo-compiler
:
bash
cargo add apollo-compiler
Or add this to your Cargo.toml
for a manual installation:
```toml
[dependencies] apollo-compiler = "0.9.2" ```
apollo-compiler
is tested on the latest stable version of Rust.
Older version may or may not be compatible.
apollo-compiler
is built using [salsa
] to provide a
memoised query system on top of the AST produced by apollo-parser
.
The idea is that all relationships between GraphQL types are pre-established and pre-computed, so you are able to always find the reference to say a field Type, or a Directive.
You can get started with apollo-compiler
:
```rust
use apollo_compiler::ApolloCompiler;
let input = r#" interface Pet { name: String }
type Dog implements Pet { name: String nickname: String barkVolume: Int }
type Cat implements Pet { name: String nickname: String meowVolume: Int }
union CatOrDog = Cat | Dog
type Human { name: String pets: [Pet] }
type Query { human: Human } "#;
let mut compiler = ApolloCompiler::new(); compiler.add_document(input, "document.graphql");
let diagnostics = compiler.validate(); for diagnostic in &diagnostics { // this will pretty-print diagnostics using the miette crate. println!("{}", diagnostic); } assert!(diagnostics.is_empty()); ```
```rust use apollo_compiler::{ApolloCompiler, hir, HirDatabase}; use miette::Result;
fn main() -> Result<()> { let schema_input = r#" type User { id: ID name: String profilePic(size: Int): URL }
schema { query: User }
scalar URL @specifiedBy(url: "https://tools.ietf.org/html/rfc3986")
"#;
let query_input = r#"
query getUser {
... vipCustomer
}
#fragment definition where we want to know the field types.
fragment vipCustomer on User {
id
name
profilePic(size: 50)
}
"#;
let mut compiler = ApolloCompiler::new();
let _schema_id = compiler.add_type_system(schema_input, "schema.graphql");
let query_id = compiler.add_executable(query_input, "query.graphql");
let diagnostics = compiler.validate();
for diagnostic in &diagnostics {
println!("{}", diagnostic);
}
assert!(diagnostics.is_empty());
let op = compiler.db.find_operation(query_id, Some("getUser".into()))
.expect("getUser query does not exist");
let fragment_in_op: Vec<hir::FragmentDefinition> = op.selection_set().selection().iter().filter_map(|sel| match sel {
hir::Selection::FragmentSpread(frag) => {
Some(frag.fragment(&compiler.db)?.as_ref().clone())
}
_ => None
}).collect();
let fragment_fields: Vec<hir::Field> = fragment_in_op.iter().flat_map(|frag| frag.selection_set().fields()).collect();
let field_ty: Vec<String> = fragment_fields
.iter()
.filter_map(|f| Some(f.ty(&compiler.db)?.name()))
.collect();
assert_eq!(field_ty, ["ID", "String", "URL"]);
Ok(())
} ```
```rust use apollo_compiler::{ApolloCompiler, hir, HirDatabase}; use anyhow::{anyhow, Result};
fn main() -> Result<()> { let schema_input = r#" type Query { topProducts: Product name: String size: Int }
type Product {
inStock: Boolean @join__field(graph: INVENTORY)
name: String @join__field(graph: PRODUCTS)
price: Int
shippingEstimate: Int
upc: String!
weight: Int
}
directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet) on FIELD_DEFINITION
"#;
let query_input = r#"
query getProduct {
size
topProducts {
name
inStock
}
}
"#;
let mut compiler = ApolloCompiler::new();
compiler.add_type_system(schema_input, "schema.graphql");
let query_id = compiler.add_executable(query_input, "query.graphql");
let diagnostics = compiler.validate();
for diagnostic in &diagnostics {
println!("{}", diagnostic);
}
assert!(diagnostics.is_empty());
let operations = compiler.db.operations(query_id);
let get_product_op = operations
.iter()
.find(|op| op.name() == Some("getProduct"))
.expect("getProduct query does not exist");
let op_fields = get_product_op.fields(&compiler.db);
let in_stock_field = op_fields
.iter()
.find(|f| f.name() == "topProducts")
.expect("topProducts field does not exist")
.selection_set()
.field("inStock")
.expect("inStock field does not exist")
.field_definition(&compiler.db)
.expect("field definition does not exist");
let in_stock_directive: Vec<&str> = in_stock_field
.directives()
.iter()
.map(|dir| dir.name())
.collect();
assert_eq!(in_stock_directive, ["join__field"]);
Ok(())
} ```
```rust use apollo_compiler::ApolloCompiler;
let input = r#" query { cat { name } }
query getPet { cat { owner { name } } }
query getPet { cat { treat } }
subscription sub { newMessage { body sender } disallowedSecondRootField }
type Query { cat: Pet }
type Subscription { newMessage: Result }
interface Pet { name: String }
type Dog implements Pet { name: String nickname: String barkVolume: Int }
type Cat implements Pet { name: String nickname: String meowVolume: Int }
union CatOrDog = Cat | Dog "#;
let mut compiler = ApolloCompiler::new(); compiler.add_document(input, "document.graphql");
let diagnostics = compiler.validate(); for diagnostic in &diagnostics { println!("{}", diagnostic) } assert_eq!(diagnostics.len(), 9) ```
Licensed under either of
at your option.