async-graphql/docs/en/src/define_complex_object.md
Edward Rudd 3b7ed74d11 correct doc examples so they compile
- examples to fix still
  - error_extensions.md ResultExt example does not compile!
     - trait ErrorExtensions is not implemented for ParseIntError
  - dataloader
     - requires sqlx to work. So we either "stub" it OR we rewrite them simpler to use a  simple "faux" db library
2022-06-02 17:32:12 -04:00

1.6 KiB

Object

Different from SimpleObject, Object must have a resolver defined for each field in its impl.

A resolver function has to be asynchronous. The first argument has to be &self, the second is an optional Context and it is followed by field arguments.

The resolver is used to get the value of the field. For example, you can query a database and return the result. The return type of the function is the type of the field. You can also return a async_graphql::Result to return an error if it occurs. The error message will then be sent as query result.

You may need access to global data in your query, for example a database connection pool. When creating your Schema, you can use SchemaBuilder::data to configure the global data, and Context::data to configure Context data. The following value_from_db function shows how to retrieve a database connection from Context.

# extern crate async_graphql;
# struct Data { pub name: String }
# struct DbConn {}
# impl DbConn {
#   fn query_something(&self, id: i64) -> std::result::Result<Data, String> { Ok(Data {name:"".into()})}
# }
# struct DbPool {}
# impl DbPool {
#   fn take(&self) -> DbConn { DbConn {} }    
# }
use async_graphql::*;

struct MyObject {
    value: i32,
}

#[Object]
impl MyObject {
    async fn value(&self) -> String {
        self.value.to_string()
    }

    async fn value_from_db(
        &self,
        ctx: &Context<'_>,
        #[graphql(desc = "Id of object")] id: i64
    ) -> Result<String> {
        let conn = ctx.data::<DbPool>()?.take();
        Ok(conn.query_something(id)?.name)
    }
}