Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

#![expect(unused_variables, reason = "example")]
extern crate juniper;
use juniper::{GraphQLInputObject, GraphQLObject, graphql_object};

#[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.