Skip to content

Commit d3ff968

Browse files
joshuapaulallenrstoyanchev
authored andcommitted
Exempt unresolvable federated entities from checks
Update check ensuring federated types have @EntityMapping to exempt entities with 'resolvable: false', since by definition those should not have an @EntityMapping. See gh-1225 Signed-off-by: Josh Allen <[email protected]>
1 parent 1f9a21e commit d3ff968

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
import com.apollographql.federation.graphqljava.Federation;
2828
import com.apollographql.federation.graphqljava.SchemaTransformer;
29+
import graphql.language.Argument;
30+
import graphql.language.BooleanValue;
31+
import graphql.language.Directive;
2932
import graphql.language.TypeDefinition;
3033
import graphql.schema.DataFetcher;
3134
import graphql.schema.GraphQLSchema;
@@ -190,19 +193,31 @@ public SchemaTransformer createSchemaTransformer(TypeDefinitionRegistry registry
190193
private void checkEntityMappings(TypeDefinitionRegistry registry) {
191194
List<String> unmappedEntities = new ArrayList<>();
192195
for (TypeDefinition<?> type : registry.types().values()) {
193-
type.getDirectives().forEach((directive) -> {
194-
boolean isEntityType = directive.getName().equalsIgnoreCase("key");
195-
if (isEntityType && !this.handlerMethods.containsKey(type.getName())) {
196-
unmappedEntities.add(type.getName());
197-
}
198-
});
196+
if (isEntityMappingExpected(type) && !this.handlerMethods.containsKey(type.getName())) {
197+
unmappedEntities.add(type.getName());
198+
}
199199
}
200200
if (!unmappedEntities.isEmpty()) {
201201
throw new IllegalStateException("Unmapped entity types: " +
202202
unmappedEntities.stream().collect(Collectors.joining("', '", "'", "'")));
203203
}
204204
}
205205

206+
/**
207+
* Determine if a handler method is expected for this type: there is at least one '@key' directive
208+
* whose 'resolvable' argument resolves to true (either explicitly, or if the argument is not set).
209+
* @param type the type to inspect.
210+
* @return true if a handler method is expected for this type
211+
*/
212+
private boolean isEntityMappingExpected(TypeDefinition<?> type) {
213+
List<Directive> keyDirectives = type.getDirectives("key");
214+
return !keyDirectives.isEmpty() && keyDirectives.stream()
215+
.anyMatch((keyDirective) -> {
216+
Argument resolvableArg = keyDirective.getArgument("resolvable");
217+
return resolvableArg == null ||
218+
(resolvableArg.getValue() instanceof BooleanValue) && ((BooleanValue) resolvableArg.getValue()).isValue();
219+
});
220+
}
206221

207222
public record EntityMappingInfo(String typeName, HandlerMethod handlerMethod) {
208223

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
extend schema @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@extends", "@external"] )
2+
13
type Book @key(fields: "id") @extends {
24
id: ID! @external
35
author: Author
6+
publisher: Publisher
47
}
58

69
type Author {
710
id: ID
811
firstName: String
912
lastName: String
1013
}
14+
15+
type Publisher @key(fields: "id", resolvable: false) {
16+
id: ID! @external
17+
}

0 commit comments

Comments
 (0)