[−][src]Trait async_graphql::DataSource
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; #[SimpleObject] struct DiffFields { diff: i32, } struct Numbers; #[DataSource] impl DataSource for Numbers { type Element = i32; type EdgeFieldsObj = DiffFields; async fn query_operation(&mut self, ctx: &Context<'_>, operation: &QueryOperation) -> FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>> { let (start, end) = match operation { QueryOperation::First {limit} => { let start = 0; let end = start + *limit as i32; (start, end) } QueryOperation::Last {limit} => { let end = 0; let start = end - *limit as i32; (start, end) } QueryOperation::FirstAfter {after, limit} => { let start = base64::decode(after.to_string()) .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::LastBefore {before, limit} => { let end = base64::decode(before.to_string()) .ok() .and_then(|data| data.as_slice().read_i32::<BE>().ok()) .unwrap_or(0); let start = end - *limit as i32; (start, end) } // You should handle all cases instead of using a default like this _ => (0, 10) }; let nodes = (start..end).into_iter().map(|n| (base64::encode(n.to_be_bytes()).into(), DiffFields {diff: n - 1000}, n)).collect(); Ok(Connection::new(None, true, true, nodes)) } } #[Object] impl QueryRoot { async fn numbers(&self, ctx: &Context<'_>, after: Option<Cursor>, before: Option<Cursor>, 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
Fields for Edge
Is a type that implements ObjectType and can be defined by the procedure macro #[Object].
Required methods
#[must_use]fn query_operation<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
&'life0 mut self,
ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
Parses the parameters and executes the query,Usually you just need to implement this method.
Provided methods
#[must_use]fn query<'life0, 'life1, 'life2, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context<'life2>,
after: Option<Cursor>,
before: Option<Cursor>,
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,
&'life0 mut self,
ctx: &'life1 Context<'life2>,
after: Option<Cursor>,
before: Option<Cursor>,
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.
Implementations on Foreign Types
impl<'a, T: Sync> DataSource for &'a [T][src]
type Element = &'a T
type EdgeFieldsObj = EmptyEdgeFields
fn query_operation<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait, [src]
&'life0 mut self,
_ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
impl<'a, T, E> DataSource for BoxStream<'a, (Cursor, E, T)> where
T: Send + 'a,
E: ObjectType + Send + 'a, [src]
T: Send + 'a,
E: ObjectType + Send + 'a,
You can use a Pin<Box<Stream<Item = (Cursor, E, T)>>> as a datasource
Examples
use async_graphql::*; use byteorder::{ReadBytesExt, BE}; use futures::StreamExt; struct QueryRoot; #[Object] impl QueryRoot { async fn stream_connection(&self, ctx: &Context<'_>, after: Option<Cursor>, before: Option<Cursor>, first: Option<i32>, last: Option<i32> ) -> FieldResult<Connection<&str>> { let mut edges_stream = futures::stream::iter(vec!["a", "b", "c", "d", "e", "f"]) .map(|node| { let cursor: Cursor = node.to_owned().into(); (cursor, EmptyEdgeFields, node) }) .boxed(); edges_stream.query(ctx, after, before, first, last).await } } #[async_std::main] async fn main() { let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription); assert_eq!( schema .execute("{ streamConnection(first: 2) { edges { node } } }") .await .unwrap() .data, serde_json::json!({ "streamConnection": { "edges": [ { "node": "a" }, { "node": "b" } ] }, }) ); assert_eq!( schema .execute("{ streamConnection(last: 2) { edges { node } } }") .await .unwrap() .data, serde_json::json!({ "streamConnection": { "edges": [ { "node": "e" }, { "node": "f" } ] }, }) ); }
type Element = T
type EdgeFieldsObj = E
fn query_operation<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait, [src]
&'life0 mut self,
_ctx: &'life1 Context<'life2>,
operation: &'life3 QueryOperation
) -> Pin<Box<dyn Future<Output = FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,