Crate apollo_compiler
source ·Expand description
§Features
- A (comparatively) low-level AST for GraphQL grammar,
and high-level representation of SchemaandExecutableDocument.
- All three can be parsed (using apollo-parserinternally), created or modified programatically, and serialized.
- Validation of schemas and executable documents, as defined in the GraphQL specification.
§Getting started
Add the dependency to start using apollo-compiler:
cargo add apollo-compiler
Or add this to your Cargo.toml for a manual installation:
# Just an example, change to the necessary package version.
# Using an exact dependency is recommended for beta versions
[dependencies]
apollo-compiler = "=1.0.0-beta.19"
§Rust versions
apollo-compiler is tested on the latest stable version of Rust.
Older version may or may not be compatible.
§Usage
You can get started with apollo-compiler:
use apollo_compiler::Schema;
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
  }
"#;
/// In case of validation errors, the panic message will be nicely formatted
/// to point at relevant parts of the source file(s)
let schema = Schema::parse_and_validate(input, "document.graphql").unwrap();§Examples
§Accessing fragment definition field types
use apollo_compiler::{Schema, ExecutableDocument, Node, executable};
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 schema = Schema::parse_and_validate(schema_input, "schema.graphql").unwrap();
let document = ExecutableDocument::parse_and_validate(&schema, query_input, "query.graphql")
    .unwrap();
let op = document.operations.get(Some("getUser")).expect("getUser query does not exist");
let fragment_in_op = op.selection_set.selections.iter().filter_map(|sel| match sel {
    executable::Selection::FragmentSpread(spread) => {
        Some(document.fragments.get(&spread.fragment_name)?.as_ref())
    }
    _ => None
}).collect::<Vec<&executable::Fragment>>();
let fragment_fields = fragment_in_op.iter().flat_map(|frag| {
    frag.selection_set.fields()
}).collect::<Vec<&Node<executable::Field>>>();
let field_ty = fragment_fields
    .iter()
    .map(|f| f.ty().inner_named_type().as_str())
    .collect::<Vec<&str>>();
assert_eq!(field_ty, ["ID", "String", "URL"]);§Get a directive defined on a field used in a query operation definition.
use apollo_compiler::{Schema, ExecutableDocument, Node, executable};
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
}
enum join__Graph {
  INVENTORY,
  PRODUCTS,
}
scalar join__FieldSet
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 schema = Schema::parse_and_validate(schema_input, "schema.graphql").unwrap();
let document = ExecutableDocument::parse_and_validate(&schema, query_input, "query.graphql")
    .unwrap();
let get_product_op = document
    .operations
    .get(Some("getProduct"))
    .expect("getProduct query does not exist");
let in_stock_field = &get_product_op
    .selection_set
    .fields()
    .find(|f| f.name == "topProducts")
    .expect("topProducts field does not exist")
    .selection_set
    .fields()
    .find(|f| f.name == "inStock")
    .expect("inStock field does not exist")
    .definition;
let in_stock_directive: Vec<_> = in_stock_field
    .directives
    .iter()
    .map(|dir| &dir.name)
    .collect();
assert_eq!(in_stock_directive, ["join__field"]);§Printing diagnostics for a faulty GraphQL document
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
"#;
if let Err(diagnostics) = apollo_compiler::parse_mixed_validate(input, "document.graphql") {
    println!("{diagnostics}")
}§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.
Re-exports§
- pub use self::executable::ExecutableDocument;
- pub use self::parser::parse_mixed_validate;
- pub use self::schema::Schema;
Modules§
- Abstract Syntax Tree for GraphQL documents. Lower-level thanSchemaorExecutableDocument.
- Type aliases for hashing-based collections configured with a specific hasher, as used in various places thorough the API
- Parsing and printing for schema coordinates as described in the RFC.
- Pretty-printable diagnostic reports for errors that reference GraphQL documents.
- High-level representation of an executable document, which can contain operations and fragments.
- APIs related to executing a GraphQL request and returning a GraphQL response
- APIs related to parsing&strinputs as GraphQL syntax
- High-level representation of a GraphQL schema
- Supporting APIs for GraphQL validation and other kinds of errors.
Macros§
- Create a static schema coordinate at compile time.
- Create aNamefrom a string literal or identifier, checked for validity at compile time.
- Create a staticTypewith GraphQL-like syntax
Structs§
- Tried to create aNamefrom a string that is not in valid GraphQL name syntax.
- A GraphQL identifier
- A thread-safe reference-counted smart pointer for GraphQL nodes.