From 4bdd28d966ed89c48b7062369577a3d687794001 Mon Sep 17 00:00:00 2001 From: Damien Pontifex Date: Wed, 17 Aug 2022 10:36:00 +0800 Subject: [PATCH] additions so type can also be shareable as well as field --- derive/src/args.rs | 5 +++++ derive/src/merged_object.rs | 2 ++ derive/src/merged_subscription.rs | 1 + derive/src/object.rs | 3 +++ derive/src/simple_object.rs | 3 +++ derive/src/subscription.rs | 1 + docs/en/src/apollo_federation.md | 2 ++ src/registry/export_sdl.rs | 4 ++++ src/registry/mod.rs | 3 +++ src/types/empty_mutation.rs | 1 + src/types/empty_subscription.rs | 1 + src/types/merged_object.rs | 3 +++ tests/federation.rs | 23 +++++++++++++++++++---- 13 files changed, 48 insertions(+), 4 deletions(-) diff --git a/derive/src/args.rs b/derive/src/args.rs index faf69cd6..6a5f8cd0 100644 --- a/derive/src/args.rs +++ b/derive/src/args.rs @@ -200,6 +200,8 @@ pub struct SimpleObject { #[darling(default)] pub extends: bool, #[darling(default)] + pub shareable: bool, + #[darling(default)] pub visible: Option, #[darling(default, multiple, rename = "concrete")] pub concretes: Vec, @@ -237,6 +239,7 @@ pub struct Object { pub rename_args: Option, pub cache_control: CacheControl, pub extends: bool, + pub shareable: bool, pub use_type_description: bool, pub visible: Option, pub serial: bool, @@ -599,6 +602,8 @@ pub struct MergedObject { #[darling(default)] pub extends: bool, #[darling(default)] + pub shareable: bool, + #[darling(default)] pub visible: Option, #[darling(default)] pub serial: bool, diff --git a/derive/src/merged_object.rs b/derive/src/merged_object.rs index e0ee880e..2da26995 100644 --- a/derive/src/merged_object.rs +++ b/derive/src/merged_object.rs @@ -14,6 +14,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult GeneratorResult GeneratorResult(), } diff --git a/derive/src/object.rs b/derive/src/object.rs index 5492e590..3791c581 100644 --- a/derive/src/object.rs +++ b/derive/src/object.rs @@ -26,6 +26,7 @@ pub fn generate( 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 extends = object_args.extends; + let shareable = object_args.shareable; let gql_typename = if !object_args.name_type { object_args .name @@ -642,6 +643,7 @@ pub fn generate( }, cache_control: #cache_control, extends: #extends, + shareable: #shareable, keys: ::std::option::Option::None, visible: #visible, is_subscription: false, @@ -681,6 +683,7 @@ pub fn generate( }, cache_control: #cache_control, extends: #extends, + shareable: #shareable, keys: ::std::option::Option::None, visible: #visible, is_subscription: false, diff --git a/derive/src/simple_object.rs b/derive/src/simple_object.rs index 73bdb9c9..d274fc67 100644 --- a/derive/src/simple_object.rs +++ b/derive/src/simple_object.rs @@ -30,6 +30,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult GeneratorResult GeneratorResult(), }) diff --git a/docs/en/src/apollo_federation.md b/docs/en/src/apollo_federation.md index 578f8edb..93d515d5 100644 --- a/docs/en/src/apollo_federation.md +++ b/docs/en/src/apollo_federation.md @@ -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 `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 ```rust diff --git a/src/registry/export_sdl.rs b/src/registry/export_sdl.rs index aee75ddd..472f144c 100644 --- a/src/registry/export_sdl.rs +++ b/src/registry/export_sdl.rs @@ -201,6 +201,7 @@ impl Registry { extends, keys, description, + shareable, .. } => { if Some(name.as_str()) == self.subscription_type.as_deref() @@ -244,6 +245,9 @@ impl Registry { write!(sdl, "@key(fields: \"{}\") ", key).ok(); } } + if *shareable { + write!(sdl, "@shareable ").ok(); + } } writeln!(sdl, "{{").ok(); diff --git a/src/registry/mod.rs b/src/registry/mod.rs index b143d29f..44648602 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -218,6 +218,7 @@ pub enum MetaType { fields: IndexMap, cache_control: CacheControl, extends: bool, + shareable: bool, keys: Option>, visible: Option, is_subscription: bool, @@ -493,6 +494,7 @@ impl Registry { fields: Default::default(), cache_control: Default::default(), extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, @@ -706,6 +708,7 @@ impl Registry { }, cache_control: Default::default(), extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, diff --git a/src/types/empty_mutation.rs b/src/types/empty_mutation.rs index 8b913c87..972040a8 100644 --- a/src/types/empty_mutation.rs +++ b/src/types/empty_mutation.rs @@ -54,6 +54,7 @@ impl OutputType for EmptyMutation { fields: Default::default(), cache_control: Default::default(), extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, diff --git a/src/types/empty_subscription.rs b/src/types/empty_subscription.rs index 2c8a3d97..c9efc7ec 100644 --- a/src/types/empty_subscription.rs +++ b/src/types/empty_subscription.rs @@ -23,6 +23,7 @@ impl SubscriptionType for EmptySubscription { fields: Default::default(), cache_control: Default::default(), extends: false, + shareable: false, keys: None, visible: None, is_subscription: true, diff --git a/src/types/merged_object.rs b/src/types/merged_object.rs index 60886974..94fb9556 100644 --- a/src/types/merged_object.rs +++ b/src/types/merged_object.rs @@ -77,6 +77,7 @@ where fields, cache_control: cc, extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, @@ -135,6 +136,7 @@ where fields, cache_control: cc, extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, @@ -168,6 +170,7 @@ impl SubscriptionType for MergedObjectTail { fields: Default::default(), cache_control: Default::default(), extends: false, + shareable: false, keys: None, visible: None, is_subscription: false, diff --git a/tests/federation.rs b/tests/federation.rs index 3fdf8c66..2de5f690 100644 --- a/tests/federation.rs +++ b/tests/federation.rs @@ -290,26 +290,41 @@ pub async fn test_entity_union() { #[tokio::test] pub async fn test_entity_shareable() { #[derive(SimpleObject)] - struct MyObj { + struct MyObjFieldShareable { #[graphql(shareable)] + field_shareable_a: i32, + } + + #[derive(SimpleObject)] + #[graphql(shareable)] + struct MyObjShareable { a: i32, } + struct Query; #[Object(extends)] impl Query { #[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!() } } let schema_sdl = Schema::new(Query, EmptyMutation, EmptySubscription) .sdl_with_options(SDLExportOptions::new().federation()); - println!("{}", schema_sdl); 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 ); }