spring-graphqlnetflix-dgs

How to exclude a nullable field in Graphql response


I am developing a graphql service which return some response elements. In my graphql schema I have defined non-nullabale and few nullable fields. My expectation is if any nullable field is null as value that field should be excluded from result.

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-actuator'
    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'
    //developmentOnly 'org.springframework.boot:spring-boot-devtools'
    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);
    }
}

Model

@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
}

As per this schema in User object dateOfBirth is nullabale field. So I want this field should be excluded from my response when this has value as null. As per response model definition @JsonInclude(JsonInclude.Include.NON_NULL) should exclude this from response. But i am always getting null as value for this field when it has null value.

Sample Request

{
    "query": "query { user(id: \"USERID\") { id firstName lastName dateOfBirth } }"
}

Sample Response

{
    "data": {
        "user": {
            "id": "2c628b4e-bef3-4794-9af5-5e8deb69817e",
            "firstName": "Jhon",
            "lastName": "Victor",
            "dateOfBirth": null // This is not suppose to be in response.
        }
    }
}

Solution

  • This is the expected behavior.

    Spring for GraphQL apps only use Jackson for Map conversion. The actual JSON format is controller by graphql-java, which sticks to the specification (here, responding with the requested selection set). Adding Jackson annotations will have no effect for this.

    If you would like to customize the response more, you can use custom scalars.