Spring Boot GraphQL Validation Digits

The Digits Validation Directive is applied to the Float and checks if it's digits before decimal and digits after decimal should be within the specified value.

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")
    Apple addApple(@Argument AppleVO appleVO) {
        return appleService.addApple(appleVO);
    }
}
package org.wesome.graphql.entity;

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

public record AppleVO(int appleId, String appleName, String taste, Float price) {
}
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();

    Apple addApple(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 Apple addApple(AppleVO appleVO) {
        Apple apple = new Apple(apples.size() + 1, appleVO.appleName(), appleVO.taste(), appleVO.price());
        apples.add(apple);
        return apple;
    }
}
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 @Digits(integer : Int!, fraction : Int, message : String = "graphql.validation.Digits.message") on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
# Apple Object
type Apple{
    # appleId
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String
    # apple price
    price:Float
}
# Apple Input Object
input AppleVO{
    # apple Name
    appleName:String
    # apple Taste
    taste:String
    # apple price
    price:Float @Digits(integer : 2, fraction : 2)
}
# Apple Query
type Query{
    # query to get Apple
    findAllApple:[Apple]
}
# Apple Mutation
type Mutation{
    # mutation to add an apple
    addApple(appleVO:AppleVO):Apple
}

\src\main\resources\application.properties

spring.graphql.graphiql.enabled=true

\src\main\resources\ValidationMessages.properties

graphql.validation.Digits.message={path} numeric value out of bounds, {integer} digits and {fraction} decimal digits expected

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 {
    addApple(appleVO: { appleName: "Fuji", taste: "sweet", price: 111.0 }) {
        appleId
        appleName
        appleTaste
        price
    }
}

follow us on