[][src]Trait async_graphql::DataSource

pub trait DataSource: Sync + Send {
    type Element;
    type Edge: ObjectType + Send + Sync;
    fn query_operation<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation: &'life1 QueryOperation<'life2>
    ) -> Pin<Box<dyn Future<Output = Result<Connection<Self::Element, Self::Edge>>> + 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 = Result<Connection<Self::Element, Self::Edge>>> + 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 Edge = DiffFields;

    async fn query_operation(&self, operation: &QueryOperation<'_>) -> Result<Connection<Self::Element, Self::Edge>> {
        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>
    ) -> Result<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.query("{ numbers(first: 2) { edges { node } } }").execute().await.unwrap(), serde_json::json!({
        "numbers": {
            "edges": [
                {"node": 0},
                {"node": 1}
            ]
        },
    }));

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

Associated Types

type Element

type Edge: ObjectType + Send + Sync

Loading content...

Required methods

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

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 = Result<Connection<Self::Element, Self::Edge>>> + Send + 'async_trait>> where
    'life0: 'async_trait,
    'life1: 'async_trait,
    'life2: 'async_trait,
    Self: 'async_trait, 

Loading content...

Implementations on Foreign Types

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

type Element = &'a T

type Edge = EmptyEdgeFields

Loading content...

Implementors

Loading content...