Skip to content

Commit

Permalink
Configure additional GraphQL schema files
Browse files Browse the repository at this point in the history
Prior to this commit, the GraphQL auto-configuration would provide
configuration properties for specifying the locations and file
extensions of schema files to be scanned during startup.

This commit adds a new "spring.graphql.schema.additional-files" that
applications can use to point at particular files, like
"classpath:mylocation/schema.graphqls". These files will be parsed and
considered for the schema in addition to the scanned ones.

Closes spring-projectsgh-42792
  • Loading branch information
bclozel committed Jan 16, 2025
1 parent af49970 commit 6957557
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -96,11 +96,15 @@ public GraphQlSource graphQlSource(ResourcePatternResolver resourcePatternResolv
ObjectProvider<SubscriptionExceptionResolver> subscriptionExceptionResolvers,
ObjectProvider<Instrumentation> instrumentations, ObjectProvider<RuntimeWiringConfigurer> wiringConfigurers,
ObjectProvider<GraphQlSourceBuilderCustomizer> sourceCustomizers) {

String[] schemaLocations = properties.getSchema().getLocations();
Resource[] schemaResources = resolveSchemaResources(resourcePatternResolver, schemaLocations,
properties.getSchema().getFileExtensions());
List<Resource> schemaResources = new ArrayList<>();
schemaResources.addAll(resolveSchemaResources(resourcePatternResolver, schemaLocations,
properties.getSchema().getFileExtensions()));
schemaResources.addAll(Arrays.asList(properties.getSchema().getAdditionalFiles()));

GraphQlSource.SchemaResourceBuilder builder = GraphQlSource.schemaResourceBuilder()
.schemaResources(schemaResources)
.schemaResources(schemaResources.toArray(new Resource[0]))
.exceptionResolvers(exceptionResolvers.orderedStream().toList())
.subscriptionExceptionResolvers(subscriptionExceptionResolvers.orderedStream().toList())
.instrumentation(instrumentations.orderedStream().toList());
Expand All @@ -116,15 +120,15 @@ public GraphQlSource graphQlSource(ResourcePatternResolver resourcePatternResolv
return builder.build();
}

private Resource[] resolveSchemaResources(ResourcePatternResolver resolver, String[] locations,
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, String[] locations,
String[] extensions) {
List<Resource> resources = new ArrayList<>();
for (String location : locations) {
for (String extension : extensions) {
resources.addAll(resolveSchemaResources(resolver, location + "*" + extension));
}
}
return resources.toArray(new Resource[0]);
return resources;
}

private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, String pattern) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@
import java.util.Arrays;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.Resource;

/**
* {@link ConfigurationProperties Properties} for Spring GraphQL.
Expand Down Expand Up @@ -85,6 +86,11 @@ public static class Schema {
*/
private String[] fileExtensions = new String[] { ".graphqls", ".gqls" };

/**
* Locations of additional, individual schema files to parse.
*/
private Resource[] additionalFiles = new Resource[0];

private final Inspection inspection = new Inspection();

private final Introspection introspection = new Introspection();
Expand All @@ -107,6 +113,14 @@ public void setFileExtensions(String[] fileExtensions) {
this.fileExtensions = fileExtensions;
}

public Resource[] getAdditionalFiles() {
return this.additionalFiles;
}

public void setAdditionalFiles(Resource[] additionalFiles) {
this.additionalFiles = additionalFiles;
}

private String[] appendSlashIfNecessary(String[] locations) {
return Arrays.stream(locations)
.map((location) -> location.endsWith("/") ? location : location + "/")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -110,6 +110,19 @@ void shouldScanLocationsWithCustomExtension() {
});
}

@Test
void shouldConfigureAdditionalSchemaFiles() {
this.contextRunner
.withPropertyValues("spring.graphql.schema.additional-files=classpath:graphql/types/person.custom")
.run((context) -> {
assertThat(context).hasSingleBean(GraphQlSource.class);
GraphQlSource graphQlSource = context.getBean(GraphQlSource.class);
GraphQLSchema schema = graphQlSource.schema();
assertThat(schema.getObjectType("Book")).isNotNull();
assertThat(schema.getObjectType("Person")).isNotNull();
});
}

@Test
void shouldBackOffWithCustomGraphQlSource() {
this.contextRunner.withUserConfiguration(CustomGraphQlSourceConfiguration.class).run((context) -> {
Expand Down

0 comments on commit 6957557

Please sign in to comment.