Remove all datasource-related code and update the documentation.
This commit is contained in:
parent
c7eeec4ae8
commit
cda4498979
|
@ -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>,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
```
|
|
@ -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
|
||||
|
|
|
@ -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>>,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue
Block a user