如何在GraphQL响应中排除值为Null的可空字段
GraphQL响应自动排除Null值可空字段的解决方案
问题背景
我基于Netflix DGS框架开发GraphQL服务,Schema中定义了非空字段和可空字段,需求是当可空字段值为Null时,自动从响应结果中排除。已在User模型类添加@JsonInclude(JsonInclude.Include.NON_NULL)注解,但无效,Null字段仍会出现在响应中。
相关代码片段
构建配置(build.gradle)
plugins { id 'java' id 'org.springframework.boot' version '2.7.17' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.learntech' version = '1.0.0-SNAPSHOT' java { sourceCompatibility = '11' } dependencyManagement { imports { mavenBom 'com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:5.5.5' } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation(platform("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:5.5.5")) implementation 'com.netflix.graphql.dgs:graphql-dgs-webflux-starter:5.5.5' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.projectreactor:reactor-test' } tasks.named('test') { useJUnitPlatform() }
DataFetcher代码
@DgsComponent @Slf4j public class UserDataFetcher { private final UserSearchService userSearchService; public UserDataFetcher(UserSearchService userSearchService) { this.userSearchService = userSearchService; } @DgsQuery public Mono<List<User>> users(@InputArgument SearchInput searchInput) throws JsonProcessingException { log.info("users() Starts"); log.info("First Name {}", searchInput.getFirstName()); log.info("Last Name {}", searchInput.getLastName()); List<User> users = userSearchService.searchUser(searchInput); return Mono.just(users); } @DgsQuery public Mono<User> user(@InputArgument UUID id){ log.info("user() Starts"); User user = userSearchService.searchById(id); return Mono.just(user); } }
模型类
@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class User { private UUID id; private String firstName; private String lastName; private String dateOfBirth; private String gender; private List<Address> address; private List<Phone> phone; }
Schema定义
type Query { users(searchInput: SearchInput) : [User] user(id : ID!): User } type UserResponse{ users: [User] } type User { id: ID! firstName: String! lastName: String! dateOfBirth: String gender: String address: [Address] phone: [Phone] } type Address { type: String street1: String street2: String city: String state: String zip: Int } type Phone { type: String number: String countryCode: String } input SearchInput { firstName: String lastName: String dateOfBirth: String }
请求与响应示例
请求:
{ "query": "query { user(id: \"USERID\") { id firstName lastName dateOfBirth } }" }
当前响应(不符合需求):
{ "data": { "user": { "id": "2c628b4e-bef3-4794-9af5-5e8deb69817e", "firstName": "Jhon", "lastName": "Victor", "dateOfBirth": null // 该字段需从响应中排除 } } }
解决方案
DGS框架默认不直接使用Jackson的@JsonInclude规则处理GraphQL响应,需通过以下方式配置:
方法1:自定义DGS的ObjectMapper
创建配置类,修改DGS用于序列化响应的ObjectMapper,设置排除Null值:
@Configuration public class DgsCustomConfiguration { @Bean public ObjectMapper dgsObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 若有嵌套对象,确保嵌套类也添加了@JsonInclude(NON_NULL) return objectMapper; } }
方法2:配置GraphQL执行策略处理Null值
通过自定义执行策略,让GraphQL在构建响应时自动移除Null字段:
@Configuration public class DgsNullValueHandlingConfig { @Bean public ExecutionStrategy executionStrategy() { return new AsyncExecutionStrategy(new DefaultFieldValueInfoFactory() { @Override public FieldValueInfo fieldValueInfo(Object value, GraphQLFieldDefinition fieldDefinition) { if (value == null) { // 返回NULL标识,让GraphQL跳过该字段 return FieldValueInfo.NULL; } return super.fieldValueInfo(value, fieldDefinition); } }); } }
注意事项
- 确保所有嵌套模型类(如
Address、Phone)也添加@JsonInclude(JsonInclude.Include.NON_NULL)注解,避免嵌套Null字段出现在响应中。 - 重启服务后重新测试,验证Null字段是否被自动排除。
预期响应效果
修改配置后,当dateOfBirth为Null时,响应将自动排除该字段:
{ "data": { "user": { "id": "2c628b4e-bef3-4794-9af5-5e8deb69817e", "firstName": "Jhon", "lastName": "Victor" } } }
内容的提问来源于stack exchange,提问作者springbootlearner
相关产品推荐
相关产品推荐

