Merge pull request #765 from Miaxos/fix-federation-empty-entity
fix: issue when empty with federation spec on _Entity node
This commit is contained in:
commit
df5b119bdf
|
@ -4,6 +4,8 @@ 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).
|
||||
|
||||
- Federation's `_Entity` should not be sent if empty as it's in conflict with [GraphQL Union type validation](https://spec.graphql.org/draft/#sec-Unions.Type-Validation) [#765](https://github.com/async-graphql/async-graphql/pull/765).
|
||||
|
||||
## [3.0.17] 2021-12-16
|
||||
|
||||
- Bump poem to `1.2.2`.
|
||||
|
|
|
@ -512,7 +512,12 @@ impl Registry {
|
|||
})
|
||||
}
|
||||
|
||||
fn create_entity_type(&mut self) {
|
||||
/// Each type annotated with @key should be added to the _Entity union.
|
||||
/// If no types are annotated with the key directive, then the _Entity union
|
||||
/// and Query._entities field should be removed from the schema.
|
||||
///
|
||||
/// [Reference](https://www.apollographql.com/docs/federation/federation-spec/#resolve-requests-for-entities).
|
||||
fn create_entity_type_and_root_field(&mut self) {
|
||||
let possible_types: IndexSet<String> = self
|
||||
.types
|
||||
.values()
|
||||
|
@ -531,16 +536,69 @@ impl Registry {
|
|||
})
|
||||
.collect();
|
||||
|
||||
self.types.insert(
|
||||
"_Entity".to_string(),
|
||||
MetaType::Union {
|
||||
name: "_Entity".to_string(),
|
||||
description: None,
|
||||
possible_types,
|
||||
visible: None,
|
||||
rust_typename: "async_graphql::federation::Entity",
|
||||
},
|
||||
);
|
||||
if !possible_types.is_empty() {
|
||||
self.types.insert(
|
||||
"_Entity".to_string(),
|
||||
MetaType::Union {
|
||||
name: "_Entity".to_string(),
|
||||
description: None,
|
||||
possible_types,
|
||||
visible: None,
|
||||
rust_typename: "async_graphql::federation::Entity",
|
||||
},
|
||||
);
|
||||
|
||||
let query_root = self.types.get_mut(&self.query_type).unwrap();
|
||||
if let MetaType::Object { fields, .. } = query_root {
|
||||
fields.insert(
|
||||
"_service".to_string(),
|
||||
MetaField {
|
||||
name: "_service".to_string(),
|
||||
description: None,
|
||||
args: Default::default(),
|
||||
ty: "_Service!".to_string(),
|
||||
deprecation: Default::default(),
|
||||
cache_control: Default::default(),
|
||||
external: false,
|
||||
requires: None,
|
||||
provides: None,
|
||||
visible: None,
|
||||
compute_complexity: None,
|
||||
},
|
||||
);
|
||||
|
||||
fields.insert(
|
||||
"_entities".to_string(),
|
||||
MetaField {
|
||||
name: "_entities".to_string(),
|
||||
description: None,
|
||||
args: {
|
||||
let mut args = IndexMap::new();
|
||||
args.insert(
|
||||
"representations",
|
||||
MetaInputValue {
|
||||
name: "representations",
|
||||
description: None,
|
||||
ty: "[_Any!]!".to_string(),
|
||||
default_value: None,
|
||||
visible: None,
|
||||
is_secret: false,
|
||||
},
|
||||
);
|
||||
args
|
||||
},
|
||||
ty: "[_Entity]!".to_string(),
|
||||
deprecation: Default::default(),
|
||||
cache_control: Default::default(),
|
||||
external: false,
|
||||
requires: None,
|
||||
provides: None,
|
||||
visible: None,
|
||||
compute_complexity: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_federation_types(&mut self) {
|
||||
|
@ -580,58 +638,7 @@ impl Registry {
|
|||
},
|
||||
);
|
||||
|
||||
self.create_entity_type();
|
||||
|
||||
let query_root = self.types.get_mut(&self.query_type).unwrap();
|
||||
if let MetaType::Object { fields, .. } = query_root {
|
||||
fields.insert(
|
||||
"_service".to_string(),
|
||||
MetaField {
|
||||
name: "_service".to_string(),
|
||||
description: None,
|
||||
args: Default::default(),
|
||||
ty: "_Service!".to_string(),
|
||||
deprecation: Default::default(),
|
||||
cache_control: Default::default(),
|
||||
external: false,
|
||||
requires: None,
|
||||
provides: None,
|
||||
visible: None,
|
||||
compute_complexity: None,
|
||||
},
|
||||
);
|
||||
|
||||
fields.insert(
|
||||
"_entities".to_string(),
|
||||
MetaField {
|
||||
name: "_entities".to_string(),
|
||||
description: None,
|
||||
args: {
|
||||
let mut args = IndexMap::new();
|
||||
args.insert(
|
||||
"representations",
|
||||
MetaInputValue {
|
||||
name: "representations",
|
||||
description: None,
|
||||
ty: "[_Any!]!".to_string(),
|
||||
default_value: None,
|
||||
visible: None,
|
||||
is_secret: false,
|
||||
},
|
||||
);
|
||||
args
|
||||
},
|
||||
ty: "[_Entity]!".to_string(),
|
||||
deprecation: Default::default(),
|
||||
cache_control: Default::default(),
|
||||
external: false,
|
||||
requires: None,
|
||||
provides: None,
|
||||
visible: None,
|
||||
compute_complexity: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
self.create_entity_type_and_root_field();
|
||||
}
|
||||
|
||||
pub fn names(&self) -> Vec<String> {
|
||||
|
|
Loading…
Reference in New Issue
Block a user