Skip to content

Commit 927a62e

Browse files
BACKLOG-22337: Implement new GraphQLDirectiveProvider for validation (#396)
* Implement new GraphQLDirectiveProvider interface; fix validation issues * Add SDL extension tests * Revert directive definition workaround * Fix test data * Handle null cases
1 parent c726737 commit 927a62e

File tree

5 files changed

+104
-23
lines changed

5 files changed

+104
-23
lines changed

graphql-dxm-provider/src/main/java/org/jahia/modules/graphql/provider/dxm/DXGraphQLProvider.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@
5050
import java.util.stream.Collectors;
5151

5252
@Component(service = GraphQLProvider.class, immediate = true)
53-
public class DXGraphQLProvider implements GraphQLTypesProvider, GraphQLQueryProvider, GraphQLMutationProvider, GraphQLSubscriptionProvider, GraphQLCodeRegistryProvider, DXGraphQLExtensionsProvider {
53+
public class DXGraphQLProvider implements
54+
GraphQLTypesProvider, GraphQLQueryProvider, GraphQLMutationProvider, GraphQLDirectiveProvider,
55+
GraphQLSubscriptionProvider, GraphQLCodeRegistryProvider, DXGraphQLExtensionsProvider
56+
{
5457
private static Logger logger = LoggerFactory.getLogger(DXGraphQLProvider.class);
5558

5659
private static DXGraphQLProvider instance;
@@ -304,6 +307,11 @@ public Collection<GraphQLType> getTypes() {
304307
return types;
305308
}
306309

310+
@Override
311+
public Collection<GraphQLDirective> getDirectives() {
312+
return sdlSchemaService.getDirectives();
313+
}
314+
307315
@Override
308316
public Collection<GraphQLFieldDefinition> getQueries() {
309317
List<GraphQLFieldDefinition> defs = new ArrayList<>(queryType.getFieldDefinitions());

graphql-dxm-provider/src/main/java/org/jahia/modules/graphql/provider/dxm/sdl/parsing/SDLSchemaService.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@
5252
import java.net.URL;
5353
import java.text.MessageFormat;
5454
import java.util.*;
55+
import java.util.function.Function;
5556
import java.util.stream.Collectors;
5657

5758
import static graphql.Scalars.GraphQLBoolean;
5859
import static graphql.Scalars.GraphQLString;
60+
import static org.jahia.modules.graphql.provider.dxm.sdl.SDLConstants.*;
5961

6062
@Component(service = SDLSchemaService.class, immediate = true)
6163
public class SDLSchemaService {
@@ -198,17 +200,16 @@ public List<GraphQLFieldDefinition> getSDLQueries() {
198200

199201
List<GraphQLFieldDefinition> fieldDefinitions = graphQLSchema.getQueryType().getFieldDefinitions();
200202
for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) {
201-
GraphQLObjectType objectType = fieldDefinition.getType() instanceof GraphQLList ?
202-
(GraphQLObjectType) ((GraphQLList) fieldDefinition.getType()).getWrappedType() : (GraphQLObjectType) fieldDefinition.getType();
203-
204-
GraphQLAppliedDirective directive = objectType.getAppliedDirective(SDLConstants.MAPPING_DIRECTIVE);
203+
GraphQLDirectiveContainer directiveContainer = fieldDefinition.getType() instanceof GraphQLList ?
204+
(GraphQLDirectiveContainer) ((GraphQLList) fieldDefinition.getType()).getWrappedType() :
205+
(GraphQLDirectiveContainer) fieldDefinition.getType();
205206

207+
GraphQLAppliedDirective directive = directiveContainer.getAppliedDirective(SDLConstants.MAPPING_DIRECTIVE);
206208
if (directive == null) {
207209
continue;
208210
}
209211

210212
String nodeType = directive.getArgument(SDLConstants.MAPPING_DIRECTIVE_NODE).getValue().toString();
211-
212213
//Handle connections
213214
if (fieldDefinition.getName().contains(SDLConstants.CONNECTION_QUERY_SUFFIX)) {
214215
String queryFieldName = fieldDefinition.getName().replace(SDLConstants.CONNECTION_QUERY_SUFFIX, "");
@@ -256,6 +257,21 @@ public List<GraphQLType> getSDLTypes() {
256257
return types;
257258
}
258259

260+
public Set<GraphQLDirective> getDirectives() {
261+
Set<GraphQLDirective> result = new HashSet<>();
262+
if (graphQLSchema == null) {
263+
generateSchema();
264+
}
265+
266+
if (graphQLSchema != null) {
267+
List<GraphQLDirective> directives = graphQLSchema.getDirectives();
268+
if (directives != null) {
269+
result.addAll(directives);
270+
}
271+
}
272+
return result;
273+
}
274+
259275
public GraphQLSchema getGraphQLSchema() {
260276
return graphQLSchema;
261277
}
@@ -334,27 +350,27 @@ private void applyDefaultFetcher(final List<GraphQLFieldDefinition> defs, final
334350

335351
private TypeDefinitionRegistry prepareTypeRegistryDefinition() {
336352
TypeDefinitionRegistry typeDefinitionRegistry = new TypeDefinitionRegistry();
337-
typeDefinitionRegistry.add(new ObjectTypeDefinition("Query"));
353+
Function<GraphQLScalarType, TypeName> newType = scalar -> new TypeName(scalar.getName());
354+
355+
typeDefinitionRegistry.add(ObjectTypeDefinition.newObjectTypeDefinition().name("Query")
356+
.fieldDefinition(new FieldDefinition("_empty", newType.apply(GraphQLBoolean)))
357+
.build());
338358
typeDefinitionRegistry.add(new ScalarTypeDefinition("Date"));
339359
typeDefinitionRegistry.add(DirectiveDefinition.newDirectiveDefinition()
340360
.name(SDLConstants.MAPPING_DIRECTIVE)
341361
.directiveLocations(Arrays.asList(
342-
DirectiveLocation.newDirectiveLocation().name("OBJECT").build(),
343-
DirectiveLocation.newDirectiveLocation().name("FIELD_DEFINITION").build()))
362+
new DirectiveLocation("OBJECT"),
363+
new DirectiveLocation("FIELD_DEFINITION") ))
344364
.inputValueDefinitions(Arrays.asList(
345-
InputValueDefinition.newInputValueDefinition().name(SDLConstants.MAPPING_DIRECTIVE_NODE).type(TypeName.newTypeName(GraphQLString.getName()).build()).build(),
346-
InputValueDefinition.newInputValueDefinition().name(SDLConstants.MAPPING_DIRECTIVE_PROPERTY).type(TypeName.newTypeName(GraphQLString.getName()).build()).build(),
347-
InputValueDefinition.newInputValueDefinition().name(SDLConstants.MAPPING_DIRECTIVE_IGNORE_DEFAULT_QUERIES).type(TypeName.newTypeName(GraphQLBoolean.getName()).build()).build()))
365+
new InputValueDefinition(MAPPING_DIRECTIVE_NODE, newType.apply(GraphQLString)),
366+
new InputValueDefinition(MAPPING_DIRECTIVE_PROPERTY, newType.apply(GraphQLString)),
367+
new InputValueDefinition(MAPPING_DIRECTIVE_IGNORE_DEFAULT_QUERIES, newType.apply(GraphQLBoolean)) ))
348368
.build());
349-
350369
typeDefinitionRegistry.add(DirectiveDefinition.newDirectiveDefinition()
351-
.name(SDLConstants.FETCHER_DIRECTIVE)
352-
.directiveLocations(Arrays.asList(
353-
DirectiveLocation.newDirectiveLocation().name("FIELD_DEFINITION").build()))
354-
.inputValueDefinitions(Arrays.asList(
355-
InputValueDefinition.newInputValueDefinition().name(SDLConstants.FETCHER_DIRECTIVE_NAME).type(TypeName.newTypeName(GraphQLString.getName()).build()).build()))
370+
.name(FETCHER_DIRECTIVE)
371+
.directiveLocation(new DirectiveLocation("FIELD_DEFINITION"))
372+
.inputValueDefinition(new InputValueDefinition(FETCHER_DIRECTIVE_NAME, newType.apply(GraphQLString)))
356373
.build());
357-
358374
return typeDefinitionRegistry;
359375
}
360376

@@ -365,7 +381,7 @@ private void handleCustomConnectionTypes(TypeDefinitionRegistry typeDefinitionRe
365381
ObjectTypeExtensionDefinition query = typeDefinitionRegistry.objectTypeExtensions().get("Query").get(queryIndex);
366382
List<FieldDefinition> fields = query.getFieldDefinitions();
367383

368-
//Collect connection fields i. e. ones that map to <TypeName>Connection
384+
//Collect connection fields i.e. ones that map to <TypeName>Connection
369385
for (FieldDefinition f : fields) {
370386
if (f.getName().endsWith(SDLConstants.CONNECTION_QUERY_SUFFIX) && f.getType() instanceof TypeName) {
371387
String connectionName = ((TypeName) f.getType()).getName();

graphql-extension-example/src/main/resources/META-INF/graphql-extension.sdl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
directive @mapping(node : String, property: String, ignoreDefaultQueries: Boolean) on FIELD_DEFINITION
2-
31
"""This is news"""
42
type NewsSDL @mapping(node:"jnt:news", ignoreDefaultQueries: true) {
53
"""This is title"""
@@ -28,4 +26,4 @@ extend type Query {
2826
myNewsByDate: [NewsSDL]
2927
"""This is myImagesByHeight"""
3028
myImagesByHeight: [Images]
31-
}
29+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {
2+
getCoreSdlExtensions,
3+
getExampleSdlExtensions
4+
} from '../../fixtures/sdl/sdlExtensions';
5+
6+
describe('SDL extensions', () => {
7+
it('should have SDL extensions defined in dxm-provider module', () => {
8+
cy.apollo({query: getCoreSdlExtensions}).then((response) => {
9+
const {category, imageAsset} = response?.data || {};
10+
expect(category?.fields?.map(f => f.name)).to.deep.eq(
11+
['metadata', 'description', 'title']
12+
);
13+
expect(imageAsset?.fields?.map(f => f.name)).to.deep.eq(
14+
['metadata', 'type', 'size', 'height', 'width']
15+
);
16+
});
17+
});
18+
19+
it('should have SDL extensions defined in extension-examples module', () => {
20+
cy.apollo({query: getExampleSdlExtensions}).then((response) => {
21+
const {newsSdl, images, queries} = response?.data || {};
22+
expect(newsSdl?.fields?.map(f => f.name)).to.deep.eq(
23+
['title', 'description', 'checked', 'date']
24+
);
25+
expect(images?.fields?.map(f => f.name)).to.deep.eq(
26+
['height']
27+
);
28+
['newsByChecked', 'myNewsByDate', 'myImagesByHeight'].forEach(queryField => {
29+
expect(queries?.fields?.find(f => f.name === queryField)).to.exist;
30+
});
31+
});
32+
});
33+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import gql from 'graphql-tag';
2+
3+
export const getCoreSdlExtensions = gql`
4+
query coreSdlExtensions {
5+
category: __type(name: "Category") {
6+
fields {name}
7+
},
8+
imageAsset: __type(name: "ImageAsset") {
9+
fields {name}
10+
}
11+
}
12+
`;
13+
14+
export const getExampleSdlExtensions = gql`
15+
query exampleSdlExtensions {
16+
newsSdl: __type(name:"NewsSDL") {
17+
fields {name}
18+
}
19+
images: __type(name:"Images") {
20+
fields {name}
21+
}
22+
queries: __type(name: "Query") {
23+
fields {name}
24+
}
25+
}
26+
`;

0 commit comments

Comments
 (0)