From 6957557fd7a63f67d7653bcc8baa2c3d49619178 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 16 Jan 2025 18:15:51 +0100 Subject: [PATCH] Configure additional GraphQL schema files 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 gh-42792 --- .../graphql/GraphQlAutoConfiguration.java | 16 ++++++++++------ .../autoconfigure/graphql/GraphQlProperties.java | 16 +++++++++++++++- .../graphql/GraphQlAutoConfigurationTests.java | 15 ++++++++++++++- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java index 599b613ad4..2f997c8fb5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java @@ -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. @@ -96,11 +96,15 @@ public class GraphQlAutoConfiguration { ObjectProvider subscriptionExceptionResolvers, ObjectProvider instrumentations, ObjectProvider wiringConfigurers, ObjectProvider sourceCustomizers) { + String[] schemaLocations = properties.getSchema().getLocations(); - Resource[] schemaResources = resolveSchemaResources(resourcePatternResolver, schemaLocations, - properties.getSchema().getFileExtensions()); + List 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()); @@ -116,7 +120,7 @@ public class GraphQlAutoConfiguration { return builder.build(); } - private Resource[] resolveSchemaResources(ResourcePatternResolver resolver, String[] locations, + private List resolveSchemaResources(ResourcePatternResolver resolver, String[] locations, String[] extensions) { List resources = new ArrayList<>(); for (String location : locations) { @@ -124,7 +128,7 @@ public class GraphQlAutoConfiguration { resources.addAll(resolveSchemaResources(resolver, location + "*" + extension)); } } - return resources.toArray(new Resource[0]); + return resources; } private List resolveSchemaResources(ResourcePatternResolver resolver, String pattern) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java index 4324d47668..eee2986ddc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java @@ -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. @@ -20,6 +20,7 @@ import java.time.Duration; import java.util.Arrays; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.io.Resource; /** * {@link ConfigurationProperties Properties} for Spring GraphQL. @@ -85,6 +86,11 @@ public class GraphQlProperties { */ 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(); @@ -107,6 +113,14 @@ public class GraphQlProperties { 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 + "/") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java index f7e7543ede..ffe7c386f5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java @@ -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. @@ -110,6 +110,19 @@ class GraphQlAutoConfigurationTests { }); } + @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) -> {