additions so type can also be shareable as well as field

This commit is contained in:
Damien Pontifex 2022-08-17 10:36:00 +08:00
parent 6cfeb91f72
commit 4bdd28d966
13 changed files with 48 additions and 4 deletions

View File

@ -200,6 +200,8 @@ pub struct SimpleObject {
#[darling(default)] #[darling(default)]
pub extends: bool, pub extends: bool,
#[darling(default)] #[darling(default)]
pub shareable: bool,
#[darling(default)]
pub visible: Option<Visible>, pub visible: Option<Visible>,
#[darling(default, multiple, rename = "concrete")] #[darling(default, multiple, rename = "concrete")]
pub concretes: Vec<ConcreteType>, pub concretes: Vec<ConcreteType>,
@ -237,6 +239,7 @@ pub struct Object {
pub rename_args: Option<RenameRule>, pub rename_args: Option<RenameRule>,
pub cache_control: CacheControl, pub cache_control: CacheControl,
pub extends: bool, pub extends: bool,
pub shareable: bool,
pub use_type_description: bool, pub use_type_description: bool,
pub visible: Option<Visible>, pub visible: Option<Visible>,
pub serial: bool, pub serial: bool,
@ -599,6 +602,8 @@ pub struct MergedObject {
#[darling(default)] #[darling(default)]
pub extends: bool, pub extends: bool,
#[darling(default)] #[darling(default)]
pub shareable: bool,
#[darling(default)]
pub visible: Option<Visible>, pub visible: Option<Visible>,
#[darling(default)] #[darling(default)]
pub serial: bool, pub serial: bool,

View File

@ -14,6 +14,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream
let ident = &object_args.ident; let ident = &object_args.ident;
let (impl_generics, ty_generics, where_clause) = object_args.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = object_args.generics.split_for_impl();
let extends = object_args.extends; let extends = object_args.extends;
let shareable = object_args.shareable;
let gql_typename = object_args let gql_typename = object_args
.name .name
.clone() .clone()
@ -103,6 +104,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream
fields, fields,
cache_control, cache_control,
extends: #extends, extends: #extends,
shareable: #shareable,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
is_subscription: false, is_subscription: false,

View File

@ -74,6 +74,7 @@ pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<Token
extends: #extends, extends: #extends,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
shareable: false,
is_subscription: true, is_subscription: true,
rust_typename: ::std::any::type_name::<Self>(), rust_typename: ::std::any::type_name::<Self>(),
} }

View File

@ -26,6 +26,7 @@ pub fn generate(
let (self_ty, self_name) = get_type_path_and_name(item_impl.self_ty.as_ref())?; let (self_ty, self_name) = get_type_path_and_name(item_impl.self_ty.as_ref())?;
let (impl_generics, _, where_clause) = item_impl.generics.split_for_impl(); let (impl_generics, _, where_clause) = item_impl.generics.split_for_impl();
let extends = object_args.extends; let extends = object_args.extends;
let shareable = object_args.shareable;
let gql_typename = if !object_args.name_type { let gql_typename = if !object_args.name_type {
object_args object_args
.name .name
@ -642,6 +643,7 @@ pub fn generate(
}, },
cache_control: #cache_control, cache_control: #cache_control,
extends: #extends, extends: #extends,
shareable: #shareable,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
is_subscription: false, is_subscription: false,
@ -681,6 +683,7 @@ pub fn generate(
}, },
cache_control: #cache_control, cache_control: #cache_control,
extends: #extends, extends: #extends,
shareable: #shareable,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
is_subscription: false, is_subscription: false,

View File

@ -30,6 +30,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
let ident = &object_args.ident; let ident = &object_args.ident;
let (impl_generics, ty_generics, where_clause) = object_args.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = object_args.generics.split_for_impl();
let extends = object_args.extends; let extends = object_args.extends;
let shareable = object_args.shareable;
let gql_typename = if !object_args.name_type { let gql_typename = if !object_args.name_type {
object_args object_args
.name .name
@ -331,6 +332,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
}, },
cache_control: #cache_control, cache_control: #cache_control,
extends: #extends, extends: #extends,
shareable: #shareable,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
is_subscription: false, is_subscription: false,
@ -395,6 +397,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
}, },
cache_control: #cache_control, cache_control: #cache_control,
extends: #extends, extends: #extends,
shareable: #shareable,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
is_subscription: false, is_subscription: false,

View File

@ -409,6 +409,7 @@ pub fn generate(
extends: #extends, extends: #extends,
keys: ::std::option::Option::None, keys: ::std::option::Option::None,
visible: #visible, visible: #visible,
shareable: false,
is_subscription: true, is_subscription: true,
rust_typename: ::std::any::type_name::<Self>(), rust_typename: ::std::any::type_name::<Self>(),
}) })

View File

@ -12,6 +12,8 @@
- The `requires` directive is used to 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. - The `requires` directive is used to 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.
- The `shareable` directive is used to indicate that an object type's field is allowed to be resolved by multiple subgraphs (by default, each field can be resolved by only one subgraph).
## Entity lookup function ## Entity lookup function
```rust ```rust

View File

@ -201,6 +201,7 @@ impl Registry {
extends, extends,
keys, keys,
description, description,
shareable,
.. ..
} => { } => {
if Some(name.as_str()) == self.subscription_type.as_deref() if Some(name.as_str()) == self.subscription_type.as_deref()
@ -244,6 +245,9 @@ impl Registry {
write!(sdl, "@key(fields: \"{}\") ", key).ok(); write!(sdl, "@key(fields: \"{}\") ", key).ok();
} }
} }
if *shareable {
write!(sdl, "@shareable ").ok();
}
} }
writeln!(sdl, "{{").ok(); writeln!(sdl, "{{").ok();

View File

@ -218,6 +218,7 @@ pub enum MetaType {
fields: IndexMap<String, MetaField>, fields: IndexMap<String, MetaField>,
cache_control: CacheControl, cache_control: CacheControl,
extends: bool, extends: bool,
shareable: bool,
keys: Option<Vec<String>>, keys: Option<Vec<String>>,
visible: Option<MetaVisibleFn>, visible: Option<MetaVisibleFn>,
is_subscription: bool, is_subscription: bool,
@ -493,6 +494,7 @@ impl Registry {
fields: Default::default(), fields: Default::default(),
cache_control: Default::default(), cache_control: Default::default(),
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,
@ -706,6 +708,7 @@ impl Registry {
}, },
cache_control: Default::default(), cache_control: Default::default(),
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,

View File

@ -54,6 +54,7 @@ impl OutputType for EmptyMutation {
fields: Default::default(), fields: Default::default(),
cache_control: Default::default(), cache_control: Default::default(),
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,

View File

@ -23,6 +23,7 @@ impl SubscriptionType for EmptySubscription {
fields: Default::default(), fields: Default::default(),
cache_control: Default::default(), cache_control: Default::default(),
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: true, is_subscription: true,

View File

@ -77,6 +77,7 @@ where
fields, fields,
cache_control: cc, cache_control: cc,
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,
@ -135,6 +136,7 @@ where
fields, fields,
cache_control: cc, cache_control: cc,
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,
@ -168,6 +170,7 @@ impl SubscriptionType for MergedObjectTail {
fields: Default::default(), fields: Default::default(),
cache_control: Default::default(), cache_control: Default::default(),
extends: false, extends: false,
shareable: false,
keys: None, keys: None,
visible: None, visible: None,
is_subscription: false, is_subscription: false,

View File

@ -290,26 +290,41 @@ pub async fn test_entity_union() {
#[tokio::test] #[tokio::test]
pub async fn test_entity_shareable() { pub async fn test_entity_shareable() {
#[derive(SimpleObject)] #[derive(SimpleObject)]
struct MyObj { struct MyObjFieldShareable {
#[graphql(shareable)] #[graphql(shareable)]
field_shareable_a: i32,
}
#[derive(SimpleObject)]
#[graphql(shareable)]
struct MyObjShareable {
a: i32, a: i32,
} }
struct Query; struct Query;
#[Object(extends)] #[Object(extends)]
impl Query { impl Query {
#[graphql(entity)] #[graphql(entity)]
async fn find_obj(&self, _id: i32) -> MyObj { async fn find_obj_field_shareable(&self, _id: i32) -> MyObjFieldShareable {
todo!()
}
#[graphql(entity)]
async fn find_obj_shareable(&self, _id: i32) -> MyObjShareable {
todo!() todo!()
} }
} }
let schema_sdl = Schema::new(Query, EmptyMutation, EmptySubscription) let schema_sdl = Schema::new(Query, EmptyMutation, EmptySubscription)
.sdl_with_options(SDLExportOptions::new().federation()); .sdl_with_options(SDLExportOptions::new().federation());
println!("{}", schema_sdl);
assert_eq!( assert_eq!(
schema_sdl.contains("a: Int! @shareable"), schema_sdl.contains("fieldShareableA: Int! @shareable"),
true
);
assert_eq!(
schema_sdl.contains(r#"MyObjShareable @key(fields: "id") @shareable"#),
true true
); );
} }