Complex fields

If you've got a struct that can't be mapped directly to GraphQL, that contains computed fields or circular structures, you have to use a more powerful tool: the graphql_object! macro. This macro lets you define GraphQL objects similar to how you define methods in a Rust impl block for a type. Continuing with the example from the last chapter, this is how you would define Person using the macro:

#[macro_use] extern crate juniper;

struct Person {
    name: String,
    age: i32,
}

graphql_object!(Person: () |&self| {
    field name() -> &str {
        self.name.as_str()
    }

    field age() -> i32 {
        self.age
    }
});

While this is a bit more verbose, it lets you write any kind of function in the field resolver. With this syntax, fields can also take arguments:

#[derive(GraphQLObject)]
struct Person {
    name: String,
    age: i32,
}

struct House {
    inhabitants: Vec<Person>,
}

graphql_object!(House: () |&self| {
    // Creates the field inhabitantWithName(name), returning a nullable person
    field inhabitant_with_name(name: String) -> Option<&Person> {
        self.inhabitants.iter().find(|p| p.name == name)
    }
});

To access global data such as database connections or authentication information, a context is used. To learn more about this, see the next chapter: Using contexts.

Description, renaming, and deprecation

Like with the derive attribute, field names will be converted from snake_case to camelCase. If you need to override the conversion, you can simply rename the field. Also, the type name can be changed with an alias:

#[macro_use] extern crate juniper;

struct Person {
    name: String,
    website_url: String,
}

graphql_object!(Person: () as "PersonObject" |&self| {
    field name() -> &str {
        self.name.as_str()
    }

    field websiteURL() -> &str {
        self.website_url.as_str()
    }
});

More features

GraphQL fields expose more features than Rust's standard method syntax gives us:

  • Per-field description and deprecation messages
  • Per-argument default values
  • Per-argument descriptions

These, and more features, are described more thorougly in the reference documentation.

results matching ""

    No results matching ""