Remove all datasource-related code and update the documentation.

This commit is contained in:
Sunli 2020-06-15 14:17:19 +08:00
parent c7eeec4ae8
commit cda4498979
8 changed files with 45 additions and 149 deletions

View File

@ -832,27 +832,6 @@ impl Interface {
}
}
pub struct DataSource {
pub internal: bool,
}
impl DataSource {
pub fn parse(args: AttributeArgs) -> Result<Self> {
let mut internal = false;
for arg in args {
match arg {
NestedMeta::Meta(Meta::Path(p)) if p.is_ident("internal") => {
internal = true;
}
_ => {}
}
}
Ok(Self { internal })
}
}
pub struct Scalar {
pub internal: bool,
pub name: Option<String>,

View File

@ -15,7 +15,7 @@ mod subscription;
mod union;
mod utils;
use crate::utils::{add_container_attrs, get_crate_name, parse_derive};
use crate::utils::{add_container_attrs, parse_derive};
use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;
@ -189,23 +189,6 @@ pub fn Subscription(args: TokenStream, input: TokenStream) -> TokenStream {
}
}
#[proc_macro_attribute]
#[allow(non_snake_case)]
pub fn DataSource(args: TokenStream, input: TokenStream) -> TokenStream {
let datasource_args = match args::DataSource::parse(parse_macro_input!(args as AttributeArgs)) {
Ok(datasource_args) => datasource_args,
Err(err) => return err.to_compile_error().into(),
};
let input2: proc_macro2::TokenStream = input.clone().into();
let _item_impl = parse_macro_input!(input as ItemImpl);
let crate_name = get_crate_name(datasource_args.internal);
let expanded = quote! {
#[#crate_name::async_trait::async_trait]
#input2
};
expanded.into()
}
#[proc_macro_attribute]
#[allow(non_snake_case)]
pub fn Scalar(args: TokenStream, input: TokenStream) -> TokenStream {

View File

@ -2,62 +2,12 @@
Relay's cursor connection specification is defined to provide a consistent method for query paging. For more details on the specification see the [GraphQL Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm)。
It is simple to define a cursor connection in `Async-GraphQL`
1. Implement `async_graphql::DataSource` and write the `execute_query` function.
2. Call `DataSource::query` in the field's resolver function and return the result.
Here is a simple data source that returns continuous integers:
Define a cursor connection in `async-graphql` is very simple, you just call the `connection::query` function and query data in closure.
```rust
use async_graphql::*;
use async_graphql::connection::*;
struct Integers;
#[DataSource]
impl DataSource for Integers {
// Type for cursor
type CursorType = usize;
// Type for response
type NodeType = i32;
// We don't need to extend the connection fields, so this can be empty
type ConnectionFieldsType = EmptyFields;
// We don't need to extend the edge fields, so this can be empty
type EdgeFieldsType = EmptyFields;
async fn execute_query(
&mut self,
_ctx: &Context<'_>,
after: Option<usize>,
before: Option<usize>,
first: Option<usize>,
last: Option<usize>,
) -> FieldResult<Connection<usize, i32, EmptyFields, EmptyFields>> {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start {
end
} else {
end - last
};
}
let mut connection = Connection::new(start > 0, end < 10000);
connection.append(
(start..end).into_iter().map(|n|
Ok(Edge::new_with_additional_fields(n, n as i32, EmptyFields)),
)?;
Ok(connection)
}
}
struct Query;
#[Object]
@ -69,7 +19,26 @@ impl Query {
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<usize, i32, EmptyFields, EmptyFields>> {
Integers.query(after, before, first, last).await
query(after, before, first, last, |after, before, first, last| {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start {
end
} else {
end - last
};
}
let mut connection = Connection::new(start > 0, end < 10000);
connection.append(
(start..end).into_iter().map(|n|
Ok(Edge::new_with_additional_fields(n, n as i32, EmptyFields)),
))?;
Ok(connection)
})
}
}

View File

@ -2,10 +2,7 @@
Relay定义了一套游标连接规范以提供一致性的分页查询方式具体的规范文档请参考[GraphQL Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm)。
在`Async-graphql`中定义一个连接非常简单,只需要两步:
1. 实现`async_graphql::DataSource`,重写`execute_query`函数。
2. 在字段的Resolver函数中调用`DataSource::query`函数并传递响应参数。
在`Async-graphql`中定义一个游标连接非常简单你只需要调用connection::query函数并在闭包中查询数据。
下面是一个简单的获取连续整数的数据源:
@ -13,51 +10,6 @@ Relay定义了一套游标连接规范以提供一致性的分页查询方式
use async_graphql::*;
use async_graphql::connection::*;
struct Integers;
#[DataSource]
impl DataSource for Integers {
// 游标类型
type CursorType = usize;
// 元素类型
type NodeType = i32;
// 我们不需要扩展连接的字段所以传EmptyFields
type ConnectionFieldsType = EmptyFields;
// 我们不需要扩展边的字段所以传EmptyFields
type EdgeFieldsType = EmptyFields;
async fn execute_query(
&mut self,
_ctx: &Context<'_>,
after: Option<usize>,
before: Option<usize>,
first: Option<usize>,
last: Option<usize>,
) -> FieldResult<Connection<usize, i32, EmptyFields, EmptyFields>> {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start {
end
} else {
end - last
};
}
let mut connection = Connection::new(start > 0, end < 10000);
connection.append(
(start..end).into_iter().map(|n|
Ok(Edge::new_with_additional_fields(n, n as i32, EmptyFields)),
)?;
Ok(connection)
}
}
struct Query;
#[Object]
@ -69,8 +21,26 @@ impl Query {
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<usize, i32, EmptyFields, EmptyFields>> {
Integers.query(after, before, first, last).await
query(after, before, first, last, |after, before, first, last| {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start {
end
} else {
end - last
};
}
let mut connection = Connection::new(start > 0, end < 10000);
connection.append(
(start..end).into_iter().map(|n|
Ok(Edge::new_with_additional_fields(n, n as i32, EmptyFields)),
))?;
Ok(connection)
})
}
}
```

View File

@ -742,9 +742,6 @@ pub use async_graphql_derive::GQLUnion;
/// ```
pub use async_graphql_derive::Subscription;
/// Define a DataSource
pub use async_graphql_derive::DataSource;
/// Define a Scalar
///
/// # Macro parameters

View File

@ -12,7 +12,7 @@ use std::borrow::Cow;
/// Connection type
///
/// Connection is the result of a query for `DataSource`.
/// Connection is the result of a query for `connection::query`.
pub struct Connection<C, T, EC = EmptyFields, EE = EmptyFields> {
/// All edges of the current page.
edges: Vec<Edge<C, T, EE>>,

View File

@ -19,8 +19,6 @@ pub struct EmptyFields;
/// Parses the parameters and executes the query.
///
/// If you don't want to implement `DataSource`, you can also use this function to query data directly.
///
/// # Examples
///
/// ```rust

View File

@ -2,7 +2,7 @@ use async_graphql::connection::*;
use async_graphql::*;
#[async_std::test]
pub async fn test_datasource_additional_fields() {
pub async fn test_connection_additional_fields() {
struct QueryRoot;
#[SimpleObject]