Add support flatten
attribute for SimpleObject
, ComplexObject
and Object
macros. #533
This commit is contained in:
parent
c6bb4c026c
commit
3217f7aecd
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.0.22] 2022-1-11
|
||||
|
||||
- Add support `flatten` attribute for `SimpleObject`, `ComplexObject` and `Object` macros. [#533](https://github.com/async-graphql/async-graphql/issues/533)
|
||||
|
||||
## [3.0.21] 2022-1-11
|
||||
|
||||
- Add `Union` and `Interface` support for trait objects. [#780](https://github.com/async-graphql/async-graphql/issues/780)
|
||||
|
|
|
@ -265,6 +265,7 @@ pub struct ObjectField {
|
|||
pub complexity: Option<ComplexityType>,
|
||||
#[darling(default, multiple)]
|
||||
pub derived: Vec<DerivedField>,
|
||||
pub flatten: bool,
|
||||
}
|
||||
|
||||
#[derive(FromMeta, Default, Clone)]
|
||||
|
@ -698,6 +699,9 @@ pub struct ComplexObjectField {
|
|||
pub guard: Option<SpannedValue<String>>,
|
||||
pub visible: Option<Visible>,
|
||||
pub complexity: Option<ComplexityType>,
|
||||
#[darling(multiple)]
|
||||
pub derived: Vec<DerivedField>,
|
||||
pub flatten: bool,
|
||||
}
|
||||
|
||||
#[derive(FromMeta, Default)]
|
||||
|
|
|
@ -33,7 +33,7 @@ pub fn generate(
|
|||
let mut derived_impls = vec![];
|
||||
for item in &mut item_impl.items {
|
||||
if let ImplItem::Method(method) = item {
|
||||
let method_args: args::ObjectField =
|
||||
let method_args: args::ComplexObjectField =
|
||||
parse_graphql_attrs(&method.attrs)?.unwrap_or_default();
|
||||
|
||||
for derived in method_args.derived {
|
||||
|
@ -116,12 +116,47 @@ pub fn generate(
|
|||
|
||||
for item in &mut item_impl.items {
|
||||
if let ImplItem::Method(method) = item {
|
||||
let method_args: args::ObjectField =
|
||||
let method_args: args::ComplexObjectField =
|
||||
parse_graphql_attrs(&method.attrs)?.unwrap_or_default();
|
||||
if method_args.skip {
|
||||
remove_graphql_attrs(&mut method.attrs);
|
||||
continue;
|
||||
}
|
||||
let cfg_attrs = get_cfg_attrs(&method.attrs);
|
||||
|
||||
if method_args.flatten {
|
||||
let ty = match &method.sig.output {
|
||||
ReturnType::Type(_, ty) => OutputType::parse(ty)?,
|
||||
ReturnType::Default => {
|
||||
return Err(Error::new_spanned(
|
||||
&method.sig.output,
|
||||
"Flatten resolver must have a return type",
|
||||
)
|
||||
.into())
|
||||
}
|
||||
};
|
||||
let ty = ty.value_type();
|
||||
let ident = &method.sig.ident;
|
||||
|
||||
schema_fields.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#ty: #crate_name::ObjectType);
|
||||
<#ty>::create_type_info(registry);
|
||||
if let #crate_name::registry::MetaType::Object { fields: obj_fields, .. } =
|
||||
registry.create_fake_output_type::<#ty>() {
|
||||
fields.extend(obj_fields);
|
||||
}
|
||||
});
|
||||
|
||||
resolvers.push(quote! {
|
||||
#(#cfg_attrs)*
|
||||
if let ::std::option::Option::Some(value) = #crate_name::ContainerType::resolve_field(&self.#ident().await, ctx).await? {
|
||||
return ::std::result::Result::Ok(std::option::Option::Some(value));
|
||||
}
|
||||
});
|
||||
|
||||
remove_graphql_attrs(&mut method.attrs);
|
||||
continue;
|
||||
}
|
||||
|
||||
let field_name = method_args.name.clone().unwrap_or_else(|| {
|
||||
object_args
|
||||
|
@ -151,7 +186,6 @@ pub fn generate(
|
|||
}
|
||||
}
|
||||
};
|
||||
let cfg_attrs = get_cfg_attrs(&method.attrs);
|
||||
|
||||
let args = extract_input_args(&crate_name, method)?;
|
||||
let ty = match &method.sig.output {
|
||||
|
|
|
@ -258,6 +258,41 @@ pub fn generate(
|
|||
if method.sig.asyncness.is_none() {
|
||||
return Err(Error::new_spanned(&method, "Must be asynchronous").into());
|
||||
}
|
||||
let cfg_attrs = get_cfg_attrs(&method.attrs);
|
||||
|
||||
if method_args.flatten {
|
||||
let ty = match &method.sig.output {
|
||||
ReturnType::Type(_, ty) => OutputType::parse(ty)?,
|
||||
ReturnType::Default => {
|
||||
return Err(Error::new_spanned(
|
||||
&method.sig.output,
|
||||
"Flatten resolver must have a return type",
|
||||
)
|
||||
.into())
|
||||
}
|
||||
};
|
||||
let ty = ty.value_type();
|
||||
let ident = &method.sig.ident;
|
||||
|
||||
schema_fields.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#ty: #crate_name::ObjectType);
|
||||
<#ty>::create_type_info(registry);
|
||||
if let #crate_name::registry::MetaType::Object { fields: obj_fields, .. } =
|
||||
registry.create_fake_output_type::<#ty>() {
|
||||
fields.extend(obj_fields);
|
||||
}
|
||||
});
|
||||
|
||||
resolvers.push(quote! {
|
||||
#(#cfg_attrs)*
|
||||
if let ::std::option::Option::Some(value) = #crate_name::ContainerType::resolve_field(&self.#ident().await, ctx).await? {
|
||||
return ::std::result::Result::Ok(std::option::Option::Some(value));
|
||||
}
|
||||
});
|
||||
|
||||
remove_graphql_attrs(&mut method.attrs);
|
||||
continue;
|
||||
}
|
||||
|
||||
let field_name = method_args.name.clone().unwrap_or_else(|| {
|
||||
object_args
|
||||
|
@ -287,7 +322,6 @@ pub fn generate(
|
|||
}
|
||||
}
|
||||
};
|
||||
let cfg_attrs = get_cfg_attrs(&method.attrs);
|
||||
|
||||
let args = extract_input_args(&crate_name, method)?;
|
||||
let mut schema_args = Vec::new();
|
||||
|
|
|
@ -153,21 +153,32 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
|||
|
||||
let visible = visible_fn(&field.visible);
|
||||
|
||||
schema_fields.push(quote! {
|
||||
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
||||
name: ::std::borrow::ToOwned::to_owned(#field_name),
|
||||
description: #field_desc,
|
||||
args: ::std::default::Default::default(),
|
||||
ty: <#ty as #crate_name::OutputType>::create_type_info(registry),
|
||||
deprecation: #field_deprecation,
|
||||
cache_control: #cache_control,
|
||||
external: #external,
|
||||
provides: #provides,
|
||||
requires: #requires,
|
||||
visible: #visible,
|
||||
compute_complexity: ::std::option::Option::None,
|
||||
if !field.flatten {
|
||||
schema_fields.push(quote! {
|
||||
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
||||
name: ::std::borrow::ToOwned::to_owned(#field_name),
|
||||
description: #field_desc,
|
||||
args: ::std::default::Default::default(),
|
||||
ty: <#ty as #crate_name::OutputType>::create_type_info(registry),
|
||||
deprecation: #field_deprecation,
|
||||
cache_control: #cache_control,
|
||||
external: #external,
|
||||
provides: #provides,
|
||||
requires: #requires,
|
||||
visible: #visible,
|
||||
compute_complexity: ::std::option::Option::None,
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
schema_fields.push(quote! {
|
||||
#crate_name::static_assertions::assert_impl_one!(#ty: #crate_name::ObjectType);
|
||||
#ty::create_type_info(registry);
|
||||
if let #crate_name::registry::MetaType::Object { fields: obj_fields, .. } =
|
||||
registry.create_fake_output_type::<#ty>() {
|
||||
fields.extend(obj_fields);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let guard_map_err = quote! {
|
||||
.map_err(|err| err.into_server_error(ctx.item.pos))
|
||||
|
@ -203,27 +214,33 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
|||
false => quote! { #ty },
|
||||
};
|
||||
|
||||
getters.push(
|
||||
quote! {
|
||||
if !field.flatten {
|
||||
getters.push(quote! {
|
||||
#[inline]
|
||||
#[allow(missing_docs)]
|
||||
#vis async fn #ident(&self, ctx: &#crate_name::Context<'_>) -> #crate_name::Result<#ty> {
|
||||
::std::result::Result::Ok(#block)
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
resolvers.push(quote! {
|
||||
if ctx.item.node.name.node == #field_name {
|
||||
let f = async move {
|
||||
#guard
|
||||
self.#ident(ctx).await.map_err(|err| err.into_server_error(ctx.item.pos))
|
||||
};
|
||||
let obj = f.await.map_err(|err| ctx.set_error_path(err))?;
|
||||
let ctx_obj = ctx.with_selection_set(&ctx.item.node.selection_set);
|
||||
return #crate_name::OutputType::resolve(&obj, &ctx_obj, ctx.item).await.map(::std::option::Option::Some);
|
||||
}
|
||||
});
|
||||
resolvers.push(quote! {
|
||||
if ctx.item.node.name.node == #field_name {
|
||||
let f = async move {
|
||||
#guard
|
||||
self.#ident(ctx).await.map_err(|err| err.into_server_error(ctx.item.pos))
|
||||
};
|
||||
let obj = f.await.map_err(|err| ctx.set_error_path(err))?;
|
||||
let ctx_obj = ctx.with_selection_set(&ctx.item.node.selection_set);
|
||||
return #crate_name::OutputType::resolve(&obj, &ctx_obj, ctx.item).await.map(::std::option::Option::Some);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolvers.push(quote! {
|
||||
if let ::std::option::Option::Some(value) = #crate_name::ContainerType::resolve_field(&self.#ident, ctx).await? {
|
||||
return ::std::result::Result::Ok(std::option::Option::Some(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if !object_args.fake && resolvers.is_empty() {
|
||||
|
|
|
@ -10,45 +10,46 @@ some simple fields, and use the `ComplexObject` macro to define some other field
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| flatten | Similar to serde (flatten) | boolean | Y |
|
||||
|
||||
# Field argument attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,28 +4,28 @@ Define a directive for query.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| repeatable | It means that the directive can be used multiple times in the same location. | bool | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| locations | Specify the location where the directive is available, multiples are allowed. The possible values is "field", ... | string | N |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| repeatable | It means that the directive can be used multiple times in the same location. | bool | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| locations | Specify the location where the directive is available, multiples are allowed. The possible values is "field", ... | string | N |
|
||||
|
||||
# Directive attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,23 +4,23 @@ Define a GraphQL enum
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|---------------------------|----------|----------|
|
||||
| name | Enum name | string | Y |
|
||||
| rename_items | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| remote | Derive a remote enum | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Enum name | string | Y |
|
||||
| rename_items | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| remote | Derive a remote enum | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Item attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | Item name | string | Y |
|
||||
| deprecation | Item deprecated | bool | Y |
|
||||
| deprecation | Item deprecation reason | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Item name | string | Y |
|
||||
| deprecation | Item deprecated | bool | Y |
|
||||
| deprecation | Item deprecation reason | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,27 +4,27 @@ Define a GraphQL input object
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|-------------|----------|
|
||||
| name | Field name | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| flatten | Similar to serde (flatten) | boolean | Y |
|
||||
| skip | Skip this field, use `Default::default` to get a default value for this field. | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Field name | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| flatten | Similar to serde (flatten) | boolean | Y |
|
||||
| skip | Skip this field, use `Default::default` to get a default value for this field. | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,46 +4,46 @@ Define a GraphQL interface
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| field | Fields of this Interface | InterfaceField | N |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| field | Fields of this Interface | InterfaceField | N |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | Field name | string | N |
|
||||
| type | Field type | string | N |
|
||||
| method | Rust resolver method name. If specified, `name` will not be camelCased in schema definition | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| arg | Field arguments | InterfaceFieldArgument | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|----------|
|
||||
| name | Field name | string | N |
|
||||
| type | Field type | string | N |
|
||||
| method | Rust resolver method name. If specified, `name` will not be camelCased in schema definition | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| arg | Field arguments | InterfaceFieldArgument | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Field argument attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | N |
|
||||
| type | Argument type | string | N |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | N |
|
||||
| type | Argument type | string | N |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
|
||||
# Define an interface
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ Define a merged object with multiple object types.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ Define a merged subscription with multiple subscription types.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ It also implements `From<InnerType>` and `Into<InnerType>`.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | string | Y |
|
||||
| name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | bool | Y |
|
||||
| visible(Only valid for new scalars) | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible(Only valid for new scalars) | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| specified_by_url(Only valid for new scalars) | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | string | Y |
|
||||
| name | If this attribute is provided then define a new scalar, otherwise it is just a transparent proxy for the internal scalar. | bool | Y |
|
||||
| visible(Only valid for new scalars) | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible(Only valid for new scalars) | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| specified_by_url(Only valid for new scalars) | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -6,60 +6,61 @@ All methods are converted to camelCase.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| desc | Field description | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| flatten | Similar to serde (flatten) | boolean | Y |
|
||||
|
||||
# Field argument attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| key | Is entity key(for Federation) | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| key | Is entity key(for Federation) | bool | Y |
|
||||
|
||||
# Derived argument attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Generated derived field name | string | N |
|
||||
| into | Type to derived an into | string | Y |
|
||||
| with | Function to apply to manage advanced use cases | string| Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-----------|------------------------------------------------|--------|----------|
|
||||
| name | Generated derived field name | string | N |
|
||||
| into | Type to derived an into | string | Y |
|
||||
| with | Function to apply to manage advanced use cases | string | Y |
|
||||
|
||||
# Valid field return types
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Define a Scalar
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | Scalar name | string | Y |
|
||||
| specified_by_url | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Scalar name | string | Y |
|
||||
| specified_by_url | Provide a specification URL for this scalar type, it must link to a human-readable specification of the data format, serialization and coercion rules for this scalar. | string | Y |
|
||||
|
|
|
@ -6,43 +6,44 @@ Similar to `Object`, but defined on a structure that automatically generates get
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| concretes | Specify how the concrete type of the generic SimpleObject should be implemented. *[See also the Book](https://async-graphql.github.io/async-graphql/en/define_simple_object.html#generic-simpleobjects) | ConcreteType | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| concretes | Specify how the concrete type of the generic SimpleObject should be implemented. *[See also the Book](https://async-graphql.github.io/async-graphql/en/define_simple_object.html#generic-simpleobjects) | ConcreteType | Y |
|
||||
| serial | Resolve each field sequentially. | bool | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| owned | Field resolver return a ownedship value | bool | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|----------|
|
||||
| skip | Skip this field | bool | Y |
|
||||
| name | Field name | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| derived | Generate derived fields *[See also the Book](https://async-graphql.github.io/async-graphql/en/derived_fields.html).* | object | Y |
|
||||
| owned | Field resolver return a ownedship value | bool | Y |
|
||||
| cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||
| external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
|
||||
| provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||
| requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| flatten | Similar to serde (flatten) | boolean | Y |
|
||||
|
||||
# Derived attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Generated derived field name | string | N |
|
||||
| into | Type to derived an into | string | Y |
|
||||
| owned | Field resolver return a ownedship value | bool | Y |
|
||||
| with | Function to apply to manage advanced use cases | string| Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-----------|------------------------------------------------|--------|----------|
|
||||
| name | Generated derived field name | string | N |
|
||||
| into | Type to derived an into | string | Y |
|
||||
| owned | Field resolver return a ownedship value | bool | Y |
|
||||
| with | Function to apply to manage advanced use cases | string | Y |
|
||||
|
||||
|
||||
# Examples
|
||||
|
|
|
@ -9,42 +9,42 @@ The filter function should be synchronous.
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|---------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE". | string | Y |
|
||||
| extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||
|
||||
# Field attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | Field name | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Field name | string | Y |
|
||||
| deprecation | Field deprecated | bool | Y |
|
||||
| deprecation | Field deprecation reason | string | Y |
|
||||
| guard | Field of guard *[See also the Book](https://async-graphql.github.io/async-graphql/en/field_guard.html)* | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| complexity | Custom field complexity. *[See also the Book](https://async-graphql.github.io/async-graphql/en/depth_and_complexity.html).* | bool | Y |
|
||||
| complexity | Custom field complexity. | string | Y |
|
||||
| secret | Mark this field as a secret, it will not output the actual value in the log. | bool | Y |
|
||||
|
||||
# Field argument attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|------------------------------------------|------------ |----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|
|
||||
| name | Argument name | string | Y |
|
||||
| desc | Argument description | string | Y |
|
||||
| default | Use `Default::default` for default value | none | Y |
|
||||
| default | Argument default value | literal | Y |
|
||||
| default_with | Expression to generate default value | code string | Y |
|
||||
| validator | Input value validator *[See also the Book](https://async-graphql.github.io/async-graphql/en/input_value_validators.html)* | object | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Examples
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ Define a GraphQL union
|
|||
|
||||
# Macro attributes
|
||||
|
||||
| Attribute | description | Type | Optional |
|
||||
|-------------|---------------------------|----------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
| Attribute | description | Type | Optional |
|
||||
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------|
|
||||
| name | Object name | string | Y |
|
||||
| visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
|
||||
| visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||
|
||||
# Item attributes
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ use indexmap::IndexMap;
|
|||
use crate::extensions::ResolveInfo;
|
||||
use crate::parser::types::Selection;
|
||||
use crate::{
|
||||
Context, ContextBase, ContextSelectionSet, Name, OutputType, ServerError, ServerResult, Value,
|
||||
Context, ContextBase, ContextSelectionSet, Error, Name, OutputType, ServerError, ServerResult,
|
||||
Value,
|
||||
};
|
||||
|
||||
/// Represents a GraphQL container object.
|
||||
|
@ -84,6 +85,23 @@ impl<T: ContainerType + ?Sized> ContainerType for Box<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<T: ContainerType, E: Into<Error> + Send + Sync + Clone> ContainerType for Result<T, E> {
|
||||
async fn resolve_field(&self, ctx: &Context<'_>) -> ServerResult<Option<Value>> {
|
||||
match self {
|
||||
Ok(value) => T::resolve_field(value, ctx).await,
|
||||
Err(err) => Err(ctx.set_error_path(err.clone().into().into_server_error(ctx.item.pos))),
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_entity(&self, ctx: &Context<'_>, params: &Value) -> ServerResult<Option<Value>> {
|
||||
match self {
|
||||
Ok(value) => T::find_entity(value, ctx, params).await,
|
||||
Err(err) => Err(ctx.set_error_path(err.clone().into().into_server_error(ctx.item.pos))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve an container by executing each of the fields concurrently.
|
||||
pub async fn resolve_container<'a, T: ContainerType + ?Sized>(
|
||||
ctx: &ContextSelectionSet<'a>,
|
||||
|
|
|
@ -300,3 +300,131 @@ pub async fn test_complex_object_with_generic_concrete_type() {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_flatten() {
|
||||
#[derive(SimpleObject)]
|
||||
struct A {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
#[graphql(complex)]
|
||||
struct B {
|
||||
#[graphql(skip)]
|
||||
a: A,
|
||||
c: i32,
|
||||
}
|
||||
|
||||
#[ComplexObject]
|
||||
impl B {
|
||||
#[graphql(flatten)]
|
||||
async fn a(&self) -> &A {
|
||||
&self.a
|
||||
}
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[Object]
|
||||
impl Query {
|
||||
async fn obj(&self) -> B {
|
||||
B {
|
||||
a: A { a: 100, b: 200 },
|
||||
c: 300,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
let query = "{ __type(name: \"B\") { fields { name } } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"__type": {
|
||||
"fields": [
|
||||
{"name": "c"},
|
||||
{"name": "a"},
|
||||
{"name": "b"}
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let query = "{ obj { a b c } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"obj": {
|
||||
"a": 100,
|
||||
"b": 200,
|
||||
"c": 300,
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_flatten_with_result() {
|
||||
#[derive(SimpleObject)]
|
||||
struct A {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
#[graphql(complex)]
|
||||
struct B {
|
||||
#[graphql(skip)]
|
||||
a: A,
|
||||
c: i32,
|
||||
}
|
||||
|
||||
#[ComplexObject]
|
||||
impl B {
|
||||
#[graphql(flatten)]
|
||||
async fn a(&self) -> FieldResult<&A> {
|
||||
Ok(&self.a)
|
||||
}
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[Object]
|
||||
impl Query {
|
||||
async fn obj(&self) -> B {
|
||||
B {
|
||||
a: A { a: 100, b: 200 },
|
||||
c: 300,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
let query = "{ __type(name: \"B\") { fields { name } } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"__type": {
|
||||
"fields": [
|
||||
{"name": "c"},
|
||||
{"name": "a"},
|
||||
{"name": "b"}
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let query = "{ obj { a b c } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"obj": {
|
||||
"a": 100,
|
||||
"b": 200,
|
||||
"c": 300,
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
60
tests/object.rs
Normal file
60
tests/object.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use async_graphql::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_flatten() {
|
||||
#[derive(SimpleObject)]
|
||||
struct A {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
struct B;
|
||||
|
||||
#[Object]
|
||||
impl B {
|
||||
#[graphql(flatten)]
|
||||
async fn a(&self) -> A {
|
||||
A { a: 100, b: 200 }
|
||||
}
|
||||
|
||||
async fn c(&self) -> i32 {
|
||||
300
|
||||
}
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[Object]
|
||||
impl Query {
|
||||
async fn obj(&self) -> B {
|
||||
B
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
let query = "{ __type(name: \"B\") { fields { name } } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"__type": {
|
||||
"fields": [
|
||||
{"name": "a"},
|
||||
{"name": "b"},
|
||||
{"name": "c"}
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let query = "{ obj { a b c } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"obj": {
|
||||
"a": 100,
|
||||
"b": 200,
|
||||
"c": 300,
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
56
tests/simple_object.rs
Normal file
56
tests/simple_object.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use async_graphql::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_flatten() {
|
||||
#[derive(SimpleObject)]
|
||||
struct A {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
struct B {
|
||||
#[graphql(flatten)]
|
||||
a: A,
|
||||
c: i32,
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[Object]
|
||||
impl Query {
|
||||
async fn obj(&self) -> B {
|
||||
B {
|
||||
a: A { a: 100, b: 200 },
|
||||
c: 300,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
let query = "{ __type(name: \"B\") { fields { name } } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"__type": {
|
||||
"fields": [
|
||||
{"name": "a"},
|
||||
{"name": "b"},
|
||||
{"name": "c"}
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let query = "{ obj { a b c } }";
|
||||
assert_eq!(
|
||||
schema.execute(query).await.data,
|
||||
value!({
|
||||
"obj": {
|
||||
"a": 100,
|
||||
"b": 200,
|
||||
"c": 300,
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user