Crate juniper [−] [src]
GraphQL
GraphQL is a data query language developed by Facebook intended to serve mobile and web application frontends. A server provides a schema, containing types and fields that applications can query. Queries are hierarchical, composable, and statically typed. Schemas are introspective, which lets clients statically verify their queries against a server without actually executing them.
This library provides data types and traits to expose Rust types in a GraphQL schema, as well as an optional integration into the Iron framework. It tries to keep the number of dynamic operations to a minimum, and give you as the schema developer the control of the query execution path.
Juniper only depends on rustc-serialize
by default, making it lightweight and
easy to drop into any project. Through the iron-handlers
feature, it also
depends on Iron.
Exposing data types
The GraphQLType
trait is the primary interface towards application developers.
By deriving this trait, you can expose your types as either objects, enums,
interfaces, unions, or scalars.
However, due to the dynamic nature of GraphQL's type system, deriving this trait
manually is a bit tedious, especially in order to do it in a fully type safe
manner. To help with this task, this library provides a couple of macros; the
most common one being graphql_object!
. Use this macro to expose your already
existing object types as GraphQL objects:
#[macro_use] extern crate juniper; use juniper::FieldResult; struct User { id: String, name: String, friend_ids: Vec<String> } struct QueryRoot; struct Database { users: HashMap<String, User> } // GraphQL objects can access a "context object" during execution. Use this // object to provide e.g. database access to the field accessors. // // In this example, we use the Database struct as our context. graphql_object!(User: Database |&self| { // Expose a simple field as a GraphQL string. field id() -> &String { &self.id } field name() -> &String { &self.name } // FieldResult<T> is an alias for Result<T, String> - simply return // a string from this method and it will be correctly inserted into // the execution response. field secret() -> FieldResult<&String> { Err("Can't touch this".to_owned()) } // Field accessors can optionally take an "executor" as their first // argument. This object can help guide query execution and provides // access to the context instance. // // In this example, the context is used to convert the friend_ids array // into actual User objects. field friends(&mut executor) -> Vec<&User> { self.friend_ids.iter() .filter_map(|id| executor.context().users.get(id)) .collect() } }); // The context object is passed down to all referenced types - all your exposed // types need to have the same context type. graphql_object!(QueryRoot: Database |&self| { // Arguments work just like they do on functions. field user(&mut executor, id: String) -> Option<&User> { executor.context().users.get(&id) } });
Adding per type, field, and argument documentation is possible directly from
this macro. For more in-depth information on how to expose fields and types, see
the graphql_object!
macro.
Integrating with Iron
The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint. To support this, the library provides an optional and customizable Iron handler.
For example, continuing from the schema created above:
extern crate iron; use iron::prelude::*; use juniper::iron_handlers::GraphQLHandler; // This function is executed for every request. Here, we would realistically // provide a database connection or similar. For this example, we'll be // creating the database from scratch. fn context_factory(_: &mut Request) -> Database { Database { users: vec![ ( "1000".to_owned(), User { id: "1000".to_owned(), name: "Robin".to_owned(), friend_ids: vec!["1001".to_owned()] } ), ( "1001".to_owned(), User { id: "1001".to_owned(), name: "Max".to_owned(), friend_ids: vec!["1000".to_owned()] } ), ].into_iter().collect() } } fn main() { // GraphQLHandler takes a context factory function, the root object, // and the mutation object. If we don't have any mutations to expose, we // can use the empty tuple () to indicate absence. let graphql_endpoint = GraphQLHandler::new(context_factory, QueryRoot, ()); // Start serving the schema at the root on port 8080. Iron::new(graphql_endpoint).http("localhost:8080").unwrap(); }
See the iron_handlers
module and the GraphQLHandler
documentation
for more information on what request methods are supported. There's also a
built-in GraphiQL handler included.
Modules
meta |
Types used to describe a GraphQL schema |
parser |
Query parser and language utilities |
Macros
graphql_enum |
Expose simple enums |
graphql_input_object |
Create an input object |
graphql_interface |
Expose GraphQL interfaces |
graphql_object |
Expose GraphQL objects |
graphql_scalar |
Expose GraphQL scalars |
graphql_union |
Expose GraphQL unions |
jtry |
Helper macro to produce |
Structs
Arguments |
Field argument container |
ExecutionError |
Error type for errors that occur during query execution |
Executor |
Query execution engine |
ID |
An ID as defined by the GraphQL specification |
Registry |
A type registry used to build schemas |
RootNode |
Root query node of a schema |
RuleError |
Query validation error |
Enums
GraphQLError |
An error that prevented query execution |
InputValue |
A JSON-like value that can be passed into the query execution, either out-of-band, or in-band as default variable values. These are not constant and might contain variables. |
Selection |
Entry in a GraphQL selection set |
Type |
A type literal in the syntax tree |
TypeKind |
GraphQL type kind |
Value |
Serializable value returned from query and field execution. |
Traits
FromInputValue |
Parse an unstructured input value into a Rust data type. |
GraphQLType |
Primary trait used to expose Rust types in a GraphQL schema |
IntoFieldResult |
Convert a value into a successful field result |
ResultExt |
Helper trait to produce |
ToInputValue |
Losslessly clones a Rust data type into an InputValue. |
Functions
execute |
Execute a query in a provided schema |
Type Definitions
ExecutionResult |
The result of resolving an unspecified field |
FieldResult |
The result of resolving the value of a field of type |