Only scan for *.graphqls and *.gqls schema files

Prior to this commit, the auto-configuration was scanning for
`"*.graphql,*.gql,*.graphqls,*.gqls"` files in the configured locations.
This was not flexible enough, as developers could not customize the
considered file extensions when scanning for files.

This commit provides a new `spring.graphql.schema.file-extensions`
configuration property that enables such customizations.

Because `"*.graphql,*.gql"` extensions seem to be tied to queries
(and not schemas), this commit also changes the default value to only
consider the `"*.graphqls,*.gqls"` file extensions by default.

Closes gh-134
Closes gh-135
This commit is contained in:
Brian Clozel
2021-09-20 10:29:41 +02:00
parent 94809537cb
commit f69aa39211
6 changed files with 40 additions and 22 deletions

View File

@@ -56,8 +56,6 @@ public class GraphQlAutoConfiguration {
private static final Log logger = LogFactory.getLog(GraphQlAutoConfiguration.class);
private static final String[] SCHEMA_FILES_EXTENSIONS = new String[] {"*.graphqls", "*.graphql", "*.gql", "*.gqls"};
@Bean
public GraphQlSource graphQlSource(ResourcePatternResolver resourcePatternResolver, GraphQlProperties properties,
ObjectProvider<DataFetcherExceptionResolver> exceptionResolversProvider,
@@ -65,7 +63,8 @@ public class GraphQlAutoConfiguration {
ObjectProvider<GraphQlSourceBuilderCustomizer> sourceCustomizers,
ObjectProvider<RuntimeWiringConfigurer> wiringConfigurers) throws IOException {
List<Resource> schemaResources = resolveSchemaResources(resourcePatternResolver, properties.getSchema().getLocations());
List<Resource> schemaResources = resolveSchemaResources(resourcePatternResolver, properties.getSchema().getLocations(),
properties.getSchema().getFileExtensions());
GraphQlSource.Builder builder = GraphQlSource.builder()
.schemaResources(schemaResources.toArray(new Resource[0]))
.exceptionResolvers(exceptionResolversProvider.orderedStream().collect(Collectors.toList()))
@@ -80,15 +79,16 @@ public class GraphQlAutoConfiguration {
}
}
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, List<String> schemaLocations) throws IOException {
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, String[] schemaLocations, String[] fileExtensions) {
List<Resource> schemaResources = new ArrayList<>();
for (String location : schemaLocations) {
for (String extension : SCHEMA_FILES_EXTENSIONS) {
for (String extension : fileExtensions) {
String resourcePattern = location + "*" + extension;
try {
schemaResources.addAll(Arrays.asList(resolver.getResources(location + extension)));
schemaResources.addAll(Arrays.asList(resolver.getResources(resourcePattern)));
}
catch (IOException ex) {
logger.debug("Could not resolve schema location: '" + location + extension + "'", ex);
logger.debug("Could not resolve schema location: '" + resourcePattern + "'", ex);
}
}
}

View File

@@ -17,10 +17,7 @@
package org.springframework.graphql.boot;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Arrays;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -67,24 +64,38 @@ public class GraphQlProperties {
public static class Schema {
/**
* Locations of GraphQL '*.graphqls' schema files.
* Locations of GraphQL schema files.
*/
private List<String> locations = new ArrayList<>(Collections.singletonList("classpath:graphql/"));
private String[] locations = new String[] { "classpath:graphql/"};
/**
* File extensions for GraphQL schema files.
*/
private String[] fileExtensions = new String[] { ".graphqls", ".gqls"};
private final Printer printer = new Printer();
public List<String> getLocations() {
public String[] getLocations() {
return this.locations;
}
public void setLocations(List<String> locations) {
public void setLocations(String[] locations) {
this.locations = appendSlashIfNecessary(locations);
}
private List<String> appendSlashIfNecessary(List<String> locations) {
return locations.stream()
public String[] getFileExtensions() {
return this.fileExtensions;
}
public void setFileExtensions(String[] fileExtensions) {
this.fileExtensions = fileExtensions;
}
private String[] appendSlashIfNecessary(String[] locations) {
return Arrays.stream(locations)
.map(location -> location.endsWith("/") ? location : location + "/")
.collect(Collectors.toList());
.toArray(String[]::new);
}
public Printer getPrinter() {

View File

@@ -35,11 +35,11 @@ public class InvalidSchemaLocationsException extends NestedRuntimeException {
private final List<SchemaLocation> schemaLocations;
public InvalidSchemaLocationsException(List<String> locations, ResourcePatternResolver resolver) {
public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver) {
this(locations, resolver, null);
}
public InvalidSchemaLocationsException(List<String> locations, ResourcePatternResolver resolver, Throwable cause) {
public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver, Throwable cause) {
super("No schema file could be found in the provided locations.", cause);
List<SchemaLocation> providedLocations = new ArrayList<>();
for (String location : locations) {

View File

@@ -4,6 +4,10 @@
"name": "spring.graphql.schema.locations",
"defaultValue": "classpath:graphql/"
},
{
"name": "spring.graphql.schema.file-extensions",
"defaultValue": ".graphqls,.gqls"
},
{
"name": "management.metrics.graphql.autotime.enabled",
"description": "Whether to automatically time graphql requests.",

View File

@@ -62,7 +62,8 @@ class GraphQlAutoConfigurationTests {
@Test
void shouldScanLocationsForSchemaFiles() {
this.contextRunner.withPropertyValues("spring.graphql.schema.locations:classpath:schema/")
this.contextRunner.withPropertyValues("spring.graphql.schema.locations:classpath:schema/",
"spring.graphql.schema.file-extensions:.gql,.gqls,.graphql,.graphqls")
.run((context) -> {
assertThat(context).hasSingleBean(GraphQlSource.class);
GraphQlSource graphQlSource = context.getBean(GraphQlSource.class);

View File

@@ -1,3 +1,5 @@
management.endpoints.web.exposure.include=health,metrics,info
spring.graphql.schema.printer.enabled=true
spring.graphql.schema.printer.enabled=true
spring.graph