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

Generics

It is possible to define reusable objects using generics; however each concrete instantiation of a generic object must be given a unique GraphQL type name. There are two ways of specifying these concrete names: concrete instantiation and the TypeName trait.

Concrete Instantiation

In the following example, two SimpleObject types are created:

#![allow(unused)]
fn main() {
extern crate async_graphql;
use async_graphql::*;
#[derive(SimpleObject)]
struct SomeType { a: i32 }
#[derive(SimpleObject)]
struct SomeOtherType { a: i32 }
#[derive(SimpleObject)]
#[graphql(concrete(name = "SomeName", params(SomeType)))]
#[graphql(concrete(name = "SomeOtherName", params(SomeOtherType)))]
pub struct SomeGenericObject<T: OutputType> {
    field1: Option<T>,
    field2: String
}
}

Note: Each generic parameter must implement OutputType, as shown above.

The schema generated is:

# SomeGenericObject<SomeType>
type SomeName {
  field1: SomeType
  field2: String!
}

# SomeGenericObject<SomeOtherType>
type SomeOtherName {
  field1: SomeOtherType
  field2: String!
}

In your resolver method or field of another object, use as a normal generic type:

#![allow(unused)]
fn main() {
extern crate async_graphql;
use async_graphql::*;
#[derive(SimpleObject)]
struct SomeType { a: i32 }
#[derive(SimpleObject)]
struct SomeOtherType { a: i32 }
#[derive(SimpleObject)]
#[graphql(concrete(name = "SomeName", params(SomeType)))]
#[graphql(concrete(name = "SomeOtherName", params(SomeOtherType)))]
pub struct SomeGenericObject<T: OutputType> {
    field1: Option<T>,
    field2: String,
}
#[derive(SimpleObject)]
pub struct YetAnotherObject {
    a: SomeGenericObject<SomeType>,
    b: SomeGenericObject<SomeOtherType>,
}
}

You can pass multiple generic types to params(), separated by a comma.

TypeName trait

Some type names can be derived.

#![allow(unused)]
fn main() {
extern crate async_graphql;
use async_graphql::*;
use std::borrow::Cow;
#[derive(SimpleObject)]
#[graphql(name_type)] // Use `TypeName` trait
struct Bag<T: OutputType> {
    content: Vec<T>,
    len: usize,
}

impl<T: OutputType> TypeName for Bag<T> {
    fn type_name() -> Cow<'static, str> {
        format!("{}Bag", <T as OutputType>::type_name()).into()
    }
}
}

Using bool and String the generated schema is:

# Bag<bool>
type BooleanBag {
    content: [Boolean!]!
    len: Int!
}

# Bag<String>
type StringBag {
    content: [String!]!
    len: Int!
}