[][src]Trait async_graphql::DataSource

pub trait DataSource: Sync + Send {
    type Element;
    type EdgeFieldsObj: ObjectType + Send + Sync;
    fn query_operation<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation: &'life1 QueryOperation<'life2>
    ) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
; fn query<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        _ctx: &'life1 Context<'life2>,
        after: Option<String>,
        before: Option<String>,
        first: Option<i32>,
        last: Option<i32>
    ) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... } }

Data source of GraphQL Cursor Connections type

Edge is an extension object type that extends the edge fields, If you don't need it, you can use EmptyEdgeFields.

References

(GraphQL Cursor Connections Specification)[https://facebook.github.io/relay/graphql/connections.htm]

Examples

use async_graphql::*;
use byteorder::{ReadBytesExt, BE};

struct QueryRoot;

struct DiffFields(i32);

#[Object]
impl DiffFields {
    #[field]
    async fn diff(&self) -> i32 {
        self.0
    }
}

struct Numbers;

#[async_trait::async_trait]
impl DataSource for Numbers {
    type Element = i32;
    type EdgeFieldsObj = DiffFields;

    async fn query_operation(&self, operation: &QueryOperation<'_>) -> FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>> {
        let (start, end) = match operation {
            QueryOperation::Forward {after, limit} => {
                let start = after.and_then(|after| base64::decode(after).ok())
                    .and_then(|data| data.as_slice().read_i32::<BE>().ok())
                    .map(|idx| idx + 1)
                    .unwrap_or(0);
                let end = start + *limit as i32;
                (start, end)
            }
            QueryOperation::Backward {before, limit} => {
                let end = before.and_then(|before| base64::decode(before).ok())
                    .and_then(|data| data.as_slice().read_i32::<BE>().ok())
                    .unwrap_or(0);
                let start = end - *limit as i32;
                (start, end)
            }
        };

        let nodes = (start..end).into_iter().map(|n| (base64::encode(n.to_be_bytes()), DiffFields(n - 1000), n)).collect();
        Ok(Connection::new(None, true, true, nodes))
    }
}

#[Object]
impl QueryRoot {
    #[field]
    async fn numbers(&self, ctx: &Context<'_>,
        after: Option<String>,
        before: Option<String>,
        first: Option<i32>,
        last: Option<i32>
    ) -> FieldResult<Connection<i32, DiffFields>> {
        Numbers.query(ctx, after, before, first, last).await
    }
}

#[async_std::main]
async fn main() {
    let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription);

    assert_eq!(schema.execute("{ numbers(first: 2) { edges { node } } }").await.unwrap().data, serde_json::json!({
        "numbers": {
            "edges": [
                {"node": 0},
                {"node": 1}
            ]
        },
    }));

    assert_eq!(schema.execute("{ numbers(last: 2) { edges { node diff } } }").await.unwrap().data, serde_json::json!({
        "numbers": {
            "edges": [
                {"node": -2, "diff": -1002},
                {"node": -1, "diff": -1001}
            ]
        },
    }));
}

Associated Types

type Element

Record type

type EdgeFieldsObj: ObjectType + Send + Sync

Fields for Edge

Is a type that implements ObjectType and can be defined by the procedure macro #[Object].

Loading content...

Required methods

fn query_operation<'life0, 'life1, 'life2, 'async_trait>(
    &'life0 self,
    operation: &'life1 QueryOperation<'life2>
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
    'life0: 'async_trait,
    'life1: 'async_trait,
    'life2: 'async_trait,
    Self: 'async_trait, 

Parses the parameters and executes the query,Usually you just need to implement this method.

Loading content...

Provided methods

fn query<'life0, 'life1, 'life2, 'async_trait>(
    &'life0 self,
    _ctx: &'life1 Context<'life2>,
    after: Option<String>,
    before: Option<String>,
    first: Option<i32>,
    last: Option<i32>
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
    'life0: 'async_trait,
    'life1: 'async_trait,
    'life2: 'async_trait,
    Self: 'async_trait, 

Execute the query.

Loading content...

Implementations on Foreign Types

impl<'a, T: Sync> DataSource for &'a [T][src]

type Element = &'a T

type EdgeFieldsObj = EmptyEdgeFields

Loading content...

Implementors

Loading content...