async_graphql

Attribute Macro Object

source
#[Object]
Expand description

Define a GraphQL object with methods

See also the Book.

All methods are converted to camelCase.

§Macro attributes

AttributedescriptionTypeOptional
nameObject namestringY
rename_fieldsRename all the fields according to the given case convention. The possible values are “lowercase”, “UPPERCASE”, “PascalCase”, “camelCase”, “snake_case”, “SCREAMING_SNAKE_CASE”.stringY
rename_argsRename all the arguments according to the given case convention. The possible values are “lowercase”, “UPPERCASE”, “PascalCase”, “camelCase”, “snake_case”, “SCREAMING_SNAKE_CASE”.stringY
cache_controlObject cache controlCacheControlY
extendsAdd fields to an entity that’s defined in another serviceboolY
shareableIndicate that an object type’s field is allowed to be resolved by multiple subgraphsboolY
use_type_descriptionSpecifies that the description of the type is on the type declaration. Description(derive.Description.html)boolY
visibleIf false, it will not be displayed in introspection. See also the Book.boolY
visibleCall the specified function. If the return value is false, it will not be displayed in introspection.stringY
inaccessibleIndicate that an object is not accessible from a supergraph when using Apollo FederationboolY
tagArbitrary string metadata that will be propagated to the supergraph when using Apollo Federation. This attribute is repeatablestringY
serialResolve each field sequentially.boolY
concretesSpecify how the concrete type of the generic SimpleObject should be implemented.ConcreteTypeY
guardField of guard See also the BookstringY

§Field attributes

AttributedescriptionTypeOptional
skipSkip this fieldboolY
nameField namestringY
descField descriptionstringY
deprecationField deprecatedboolY
deprecationField deprecation reasonstringY
cache_controlField cache controlCacheControlY
externalMark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field.boolY
providesAnnotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway.stringY
requiresAnnotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services.stringY
shareableIndicate that a field is allowed to be resolved by multiple subgraphsboolY
inaccessibleIndicate that a field is not accessible from a supergraph when using Apollo FederationboolY
tagArbitrary string metadata that will be propagated to the supergraph when using Apollo Federation. This attribute is repeatablestringY
override_fromMark the field as overriding a field currently present on another subgraph. It is used to migrate fields between subgraphs.stringY
guardField of guard See also the BookstringY
visibleIf false, it will not be displayed in introspection. See also the Book.boolY
visibleCall the specified function. If the return value is false, it will not be displayed in introspection.stringY
complexityCustom field complexity. See also the Book.boolY
complexityCustom field complexity.stringY
derivedGenerate derived fields See also the Book.objectY
flattenSimilar to serde (flatten)booleanY

§Field argument attributes

AttributedescriptionTypeOptional
nameArgument namestringY
descArgument descriptionstringY
defaultUse Default::default for default valuenoneY
defaultArgument default valueliteralY
default_withExpression to generate default valuecode stringY
validatorInput value validator See also the BookobjectY
visibleIf false, it will not be displayed in introspection. See also the Book.boolY
visibleCall the specified function. If the return value is false, it will not be displayed in introspection.stringY
inaccessibleIndicate that an argument is not accessible from a supergraph when using Apollo FederationboolY
tagArbitrary string metadata that will be propagated to the supergraph when using Apollo Federation. This attribute is repeatablestringY
secretMark this field as a secret, it will not output the actual value in the log.boolY
keyIs entity key(for Federation)boolY
process_withUpon successful parsing, invokes specified function. Its signature must be fn(&mut T).code pathY

§Derived argument attributes

AttributedescriptionTypeOptional
nameGenerated derived field namestringN
intoType to derived an intostringY
withFunction to apply to manage advanced use casesstringY

§Valid field return types

  • Scalar values, such as i32 and bool. usize, isize, u128 and i128 are not supported
  • Vec<T>, such as Vec<i32>
  • Slices, such as &[i32]
  • Option<T>, such as Option<i32>
  • BTree<T>, HashMap<T>, HashSet<T>, BTreeSet<T>, LinkedList<T>, VecDeque<T>
  • GraphQL objects.
  • GraphQL enums.
  • References to any of the above types, such as &i32 or &Option<String>.
  • Result<T, E>, such as Result<i32, E>

§Context

You can define a context as an argument to a method, and the context should be the first argument to the method.

#[Object]
impl Query {
    async fn value(&self, ctx: &Context<'_>) -> { ... }
}

§Examples

Implements GraphQL Object for struct.

use async_graphql::*;

struct Query {
    value: i32,
}

#[Object]
impl Query {
    /// value
    async fn value(&self) -> i32 {
        self.value
    }

    /// reference value
    async fn value_ref(&self) -> &i32 {
        &self.value
    }

    /// value with error
    async fn value_with_error(&self) -> Result<i32> {
        Ok(self.value)
    }

    async fn value_with_arg(&self, #[graphql(default = 1)] a: i32) -> i32 {
        a
    }
}

let schema = Schema::new(Query { value: 10 }, EmptyMutation, EmptySubscription);
let res = schema.execute(r#"{
    value
    valueRef
    valueWithError
    valueWithArg1: valueWithArg
    valueWithArg2: valueWithArg(a: 99)
}"#).await.into_result().unwrap().data;
assert_eq!(res, value!({
    "value": 10,
    "valueRef": 10,
    "valueWithError": 10,
    "valueWithArg1": 1,
    "valueWithArg2": 99
}));

§Examples

Implements GraphQL Object for trait object.

use async_graphql::*;

trait MyTrait: Send + Sync {
    fn name(&self) -> &str;
}

#[Object]
impl dyn MyTrait + '_ {
    #[graphql(name = "name")]
    async fn gql_name(&self) -> &str {
        self.name()
    }
}

struct MyObj(String);

impl MyTrait for MyObj {
    fn name(&self) -> &str {
        &self.0
    }
}

struct Query;

#[Object]
impl Query {
    async fn objs(&self) -> Vec<Box<dyn MyTrait>> {
        vec![
            Box::new(MyObj("a".to_string())),
            Box::new(MyObj("b".to_string())),
        ]
    }
}

let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
let res = schema.execute("{ objs { name } }").await.into_result().unwrap().data;
assert_eq!(res, value!({
    "objs": [
        { "name": "a" },
        { "name": "b" },
    ]
}));