Spring Boot转SDL时自定义GraphQLSchema的CodeRegistry数据获取器丢失问题
解决方案:直接向Spring Boot提供完整的GraphQLSchema
问题根源在于:将已构建好的包含GraphQLCodeRegistry的GraphQLSchema转换为SDL再传入时,Spring Boot会重新解析SDL生成全新的Schema实例,原有的数据获取器、运行时wiring配置会完全丢失,导致查询时无法触发数据获取逻辑,返回null。
要避免这个问题,无需将Schema转为SDL,直接在GraphQlSourceBuilderCustomizer中传入你预先构建好的完整GraphQLSchema实例即可,具体步骤如下:
替换原有配置代码
删除通过SDL资源传入Schema的逻辑:
// 废弃:不要转SDL再传入 ByteArrayResource resource = new ByteArrayResource(schemaSdl.getBytes(StandardCharsets.UTF_8)); builder.schemaResources(resource);
改为直接传入预构建的完整Schema:
// 直接传入包含CodeRegistry的GraphQLSchema实例 builder.schema(yourPreBuiltSchema);
完整配置示例
@Configuration public class CustomGraphQLConfiguration { @Bean public GraphQlSourceBuilderCustomizer graphQlSourceBuilderCustomizer() { // 预先构建好的、包含所有wiring的GraphQLSchema GraphQLSchema schema = buildCustomSchema(); return builder -> { // 跳过SDL解析,直接使用完整Schema builder.schema(schema); }; } private GraphQLSchema buildCustomSchema() { GraphQLCodeRegistry.Builder codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry(); // 注册fetchReport的数据获取器 codeRegistryBuilder.dataFetcher( FieldCoordinates.coordinates("Query", "fetchReport"), (DataFetcher<Object>) environment -> { // 获取查询参数 String filter = environment.getArgument("filter"); Map<String, Object> report = new HashMap<>(); report.put("field1", "value1-" + filter); report.put("field2", "value2-" + filter); return report; } ); // 构建自定义Report类型 GraphQLObjectType reportType = GraphQLObjectType.newObject() .name("Report") .field(f -> f.name("field1").type(Scalars.GraphQLString)) .field(f -> f.name("field2").type(Scalars.GraphQLString)) .build(); // 构建Query类型 GraphQLObjectType queryType = GraphQLObjectType.newObject() .name("Query") .field(f -> f.name("fetchReport") .type(reportType) .argument(arg -> arg.name("filter").type(Scalars.GraphQLString))) .build(); // 生成完整Schema return GraphQLSchema.newSchema() .query(queryType) .codeRegistry(codeRegistryBuilder.build()) .build(); } }
原理说明
Spring Boot的GraphQL自动配置会优先使用你直接设置的GraphQLSchema实例,跳过SDL解析流程,这样原GraphQLCodeRegistry中注册的所有数据获取器、类型关联逻辑都会被完整保留,查询时能正常触发数据获取逻辑,返回预期结果。
内容的提问来源于stack exchange,提问作者imsilversurfer
相关产品推荐
相关产品推荐

