Input objects

Fields may accept arguments to configure their behavior. These inputs are often scalars or enums, but they sometimes need to represent more complex values.

A GraphQL input object defines a set of input fields; the input fields are either scalars, enums, or other input objects. This allows arguments to accept arbitrarily complex structs.

In Juniper, defining a GraphQL input object is quite straightforward and similar to how trivial GraphQL objects are defined - by using the #[derive(GraphQLInputObject)] attribute on a Rust struct:

#![allow(unused_variables)] extern crate juniper; use juniper::{graphql_object, GraphQLInputObject, GraphQLObject}; #[derive(GraphQLInputObject)] struct Coordinate { latitude: f64, longitude: f64 } struct Root; #[derive(GraphQLObject)] struct User { name: String } #[graphql_object] impl Root { fn users_at_location(coordinate: Coordinate, radius: f64) -> Vec<User> { // Send coordinate to database // ... unimplemented!() } } fn main() {}

Renaming

Just as with defining GraphQL objects, by default struct fields are converted from Rust's standard snake_case naming convention into GraphQL's camelCase convention:

extern crate juniper; use juniper::GraphQLInputObject; #[derive(GraphQLInputObject)] struct Person { first_name: String, // exposed as `firstName` in GraphQL schema last_name: String, // exposed as `lastName` in GraphQL schema } fn main() {}

We can override the name by using the #[graphql(name = "...")] attribute:

extern crate juniper; use juniper::GraphQLInputObject; #[derive(GraphQLInputObject)] #[graphql(name = "WebPerson")] // now exposed as `WebPerson` in GraphQL schema struct Person { name: String, age: i32, #[graphql(name = "websiteURL")] website_url: Option<String>, // now exposed as `websiteURL` in GraphQL schema } fn main() {}

Or provide a different renaming policy for all the struct fields:

extern crate juniper; use juniper::GraphQLInputObject; #[derive(GraphQLInputObject)] #[graphql(rename_all = "none")] // disables any renaming struct Person { name: String, age: i32, website_url: Option<String>, // exposed as `website_url` in GraphQL schema } fn main() {}

TIP: Supported policies are: SCREAMING_SNAKE_CASE, camelCase and none (disables any renaming).

Documentation

Similarly, GraphQL descriptions may be provided by either using Rust doc comments or with the #[graphql(description = "...")] attribute:

extern crate juniper; use juniper::GraphQLInputObject; /// This doc comment is visible only in Rust API docs. #[derive(GraphQLInputObject)] #[graphql(description = "This description is visible only in GraphQL schema.")] struct Person { /// This doc comment is visible only in Rust API docs. #[graphql(desc = "This description is visible only in GraphQL schema.")] // ^^^^ shortcut for a `description` argument name: String, /// This doc comment is visible in both Rust API docs and GraphQL schema /// descriptions. age: i32, } fn main() {}

NOTE: As of October 2021 GraphQL specification, GraphQL input object's fields cannot be deprecated.

Ignoring

By default, all struct fields are included into the generated GraphQL input object type. To prevent inclusion of a specific field annotate it with the #[graphql(ignore)] attribute:

WARNING: Ignored fields must either implement Default or be annotated with the #[graphql(default = <expression>)] argument.

extern crate juniper; use juniper::GraphQLInputObject; enum System { Cartesian, } #[derive(GraphQLInputObject)] struct Point2D { x: f64, y: f64, #[graphql(ignore, default = System::Cartesian)] // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ // This attribute is required, as we need to be able to construct // a `Point2D` value from the `{ x: 0.0, y: 0.0 }` GraphQL input value, // received from client-side. system: System, // `Default::default()` value is used, if no // `#[graphql(default = <expression>)]` is specified. #[graphql(skip)] // ^^^^ alternative naming, up to your preference shift: f64, } fn main() {}

TIP: See more available features in the API docs of the #[derive(GraphQLInputObject)] attribute.