Spring Boot GraphQL Validation ContainerSize

The ContainerSize Validation Directive is applied to the Lists, Input Objects and checks if its size is between the specified min and max boundaries.

package org.wesome.graphql.config;

import graphql.validation.rules.ValidationRules;
import graphql.validation.schemawiring.ValidationSchemaWiring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;

@Configuration
public class GraphQlConfig {
    @Bean
    RuntimeWiringConfigurer runtimeWiringConfigurer() {
        ValidationRules possibleRules = ValidationRules.newValidationRules().build();
        ValidationSchemaWiring validationDirectiveWiring = new ValidationSchemaWiring(possibleRules);
        return wiringBuilder -> wiringBuilder.directiveWiring(validationDirectiveWiring);
    }
}
package org.wesome.graphql.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import org.wesome.graphql.entity.Apple;
import org.wesome.graphql.entity.AppleVO;
import org.wesome.graphql.service.AppleService;

import java.util.List;

@Controller
public class AppleGraphQLController {
    @Autowired
    private AppleService appleService;

    @QueryMapping("findAllApple")
    List<Apple> findAllApple() {
        return appleService.findAllApple();
    }

    @MutationMapping("addApple")
    List<Apple> addApple(@Argument List<AppleVO> appleVO) {
        return appleService.addApple(appleVO);
    }
}
package org.wesome.graphql.entity;

public record Apple(int appleId, String appleName, int quantity) {
}
package org.wesome.graphql.entity;

public record AppleVO(int appleId, String appleName, int quantity) {
}
package org.wesome.graphql.service;

import org.wesome.graphql.entity.Apple;
import org.wesome.graphql.entity.AppleVO;

import java.util.List;

public interface AppleService {
    List<Apple> findAllApple();

    List<Apple> addApple(List<AppleVO> appleVO);
}
package org.wesome.graphql.service;

import org.springframework.stereotype.Service;
import org.wesome.graphql.entity.Apple;
import org.wesome.graphql.entity.AppleVO;

import java.util.ArrayList;
import java.util.List;

@Service
public class AppleServiceImpl implements AppleService {
    private static List<Apple> apples = new ArrayList<>();

    @Override
    public List<Apple> findAllApple() {
        return apples;
    }

    @Override
    public List<Apple> addApple(List<AppleVO> appleVO) {
        appleVO.stream().map(apple -> new Apple(apples.size() + 1, apple.appleName(), apple.quantity())).forEach(apples::add);
        return apples;
    }
}
package org.wesome.graphql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GraphqlProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(GraphqlProjectApplication.class, args);
    }
}

\src\main\resources\graphql\schema.graphqls

directive @ContainerSize(min : Int = 0, max : Int = 2147483647, message : String = "graphql.validation.ContainerSize.message") on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
# Apple Object
type Apple{
    # appleId
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    quantity:Int
}
# Apple Input Object
input AppleVO{
    # apple Name
    appleName:String
    # apple quantity
    quantity:Int
}
# Apple Query
type Query{
    # query to get Apple
    findAllApple:[Apple]
}
# Apple Mutation
type Mutation{
    # mutation to add list of apple
    addApple(appleVO:[AppleVO]! @ContainerSize( min : 3, max : 5)):[Apple]
}

\src\main\resources\application.properties

spring.graphql.graphiql.enabled=true

\src\main\resources\ValidationMessages.properties

graphql.validation.ContainerSize.message={path} size must be between {min} and {max}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/>
    </parent>
    <groupId>org.wesome</groupId>
    <artifactId>spring-boot-graphql</artifactId>
    <version>0.0.1-snapshot</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-graphql</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.javafaker</groupId>
            <artifactId>javafaker</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-java-extended-validation</artifactId>
            <version>21.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webflux</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.graphql</groupId>
            <artifactId>spring-graphql-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <name>spring boot graphql</name>
    <description>implementing graphql in spring boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

GraphiQL

GraphQL provides an inbuild UserInterface GraphiQL, which can be accessed via http://localhost:8080/graphiql or access GraphQL via Postmanin the query section add the below query

mutation {
    addApple(
        appleVO: [{ appleName: "Fuji", quantity: 10 }, { appleName: "Macintosh", quantity: 10 }]
    ) {
        appleId
        appleName
        quantity
    }
}

follow us on