spring-graphql
spring-graphql copied to clipboard
please support specifying a collection of resolved `Resource` instances for the individual schema files for Spring Native usage
Hi, when I want to use Spring GraphQL in a Spring Native environment, the native build fails at runtime. It cant find the graphql/schema.graphqls
file. This is because its doing classpath scanning in the GraphqlProperties
class. In Spring Native, there's no classpath. ClassPathResource
s can be made to work by providing Spring Native a configuration hint saying that a particular file is to be included in the native binary's memory, e.g,: graphql/schema.graphqls
, but ResourcePatternResolver
doesn't work.
So, the simplest solution is to just change the GraphQLProperties to also support a pre-determined array of graphqls
schema files, instead of the prefix and extension combos.
Something like this
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, Resource[] schemas, String[] schemaLocations, String[] fileExtensions) {
List<Resource> schemaResources = new ArrayList<>();
// new
if (schemas!=null && schemas.length > 0){
for ( Resource resource : schemas)
schemaResources.add(resource);
}
else {
// old
for (String location : schemaLocations) {
for (String extension : fileExtensions) {
String resourcePattern = location + "*" + extension;
try {
schemaResources.addAll(Arrays.asList(resolver.getResources(resourcePattern)));
}
catch (IOException ex) {
logger.debug("Could not resolve schema location: '" + resourcePattern + "'", ex);
}
}
}
}
return schemaResources;
}
Then, a user could easily just say spring.graphql.schema.schemas=classpath:graphql/schema.graphqls
and it would work in a graalvm spring native app, or they could use the fall through scenario searching for lcoations and extensions on the jre
I know this works because I replaced the GraphQLSource
bean definition in the auto config by copying and pasting the existing bean and then simply hardcoding the return values from private List<Resource> resolveSchemaResources
. Once I did that, and then added the following hint - @ResourceHint(patterns = "graphql/schema.graphqls")
- it built and started up just fine.
If you want to reproduce, go to start.spring.io, add the experimental Spring Native support checkbox, add Webflux, and manually add the GraphQL dependency. then run mvn -Pnative clean package
on a machine with GraalVM (im using the latest, which supports java 17) installed on which you've run gu install native-image
Hey Josh,
We haven't experimented much with native so far, so thanks for sharing your experience here. Would the following work without the properties change?
@ResourceHint(patterns = {"graphql/*.graphqls", "graphql/*.gqls"})
This is a short term solution, as it won't stay aligned with the configuration properties if the values are changed. I think we should leverage any future AOT infrastructure and prepare this work at build time in the future. Lots should be done as well with our future client support.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Hi - let me try that out now. I don't think it'll make a difference as I've tried using @ResourceHint
before and I was told it has more to do that were doing classpath scanning (where there is nothing to scan in the native world) in this case, not that we're loading multiple resources (which @ResourcehInt
would help with)
Sorry for the late update: yeeah, this doesn't work. we need to not be doing the scanning, i think.
pading @aclement who might know more about why that is, exactly
I see that since this issue was filed, the autoconfiguration has improved to support conditional registration of the GraphQlSource
and to be decoupled from the registration of the GraphQlProperties
. I've sent a (trivial, but hopefully useful) PR to support a bit of indirection in resolving the schema files. This indirection would let me use Spring GraalVM with Spring Native and I wouldn't need to recreate the GraphQlSource
. Thanks in advance for your consideration
Superseded by #495