Spring Boot GraphQL Deprecated Directive

The Rest API has a versioning system, with each upgrade, the addition of a new feature, or the depreciation of an old feature, the evaluation is supported by API versions, the initial API is always named v1, and so on. GraphQL doesn't support the versioning of the endpoint hence it provides all the data with a single URL.

Sometimes new change provides new data without actually breaking the old API contract, such as the addition of new fields but sometimes upgradation breaks the old API contract, for example, deprecating a field at all.

 
Keeping API Contract  Breaking API Contract
Old Schema New Schema
# Apple Object
type Apple{
    # primary key of apple
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String 
}

 

# Apple Object
type Apple{
    # primary key of apple
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String
    # apple price
    applePrice: Float
}
Old Schema New Schema
# Apple Object
type Apple{
    # primary key of apple
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String
    # apple price
    applePrice: Float
}
# Apple Object
type Apple{
    # primary key of apple
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String
}

 

To handle this situation, GraphQL provides a @deprecated directive. which indicates the field is deprecated with a custom message.

package org.wesome.graphql.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import org.wesome.graphql.entity.Apple;
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();
    }
}
package org.wesome.graphql.entity;

import java.util.UUID;

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

public enum AppleTaste {
    SWEET("sweet"), TANGY("tangy"), BITTER("bitter"), SOUR("sour");
    private final String appleTaste;

    AppleTaste(String appleTaste) {
        this.appleTaste = appleTaste;
    }
}
package org.wesome.graphql.service;

import org.wesome.graphql.entity.Apple;

import java.util.List;

public interface AppleService {
    List<Apple> findAllApple();
}
package org.wesome.graphql.service;


import com.github.javafaker.Faker;
import org.springframework.stereotype.Service;
import org.wesome.graphql.entity.Apple;
import org.wesome.graphql.entity.AppleTaste;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class AppleServiceImpl implements AppleService {
    private static List<Apple> apples;

    static {
        Faker faker = new Faker();
        apples = IntStream.rangeClosed(1, 10).mapToObj(value -> new Apple(value, UUID.randomUUID(), faker.food().fruit(), AppleTaste.values()[faker.random().nextInt(0, 3)].name())).collect(Collectors.toList());
    }

    @Override
    public List<Apple> findAllApple() {
        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);
    }
}
# Apple Object
type Apple{
    # appId
    appId:ID!
    @deprecated(reason: "Use UUID `appleId` instead, `appId` will be deprecated after some time.")
    # appleId
    appleId:ID!
    # apple Name
    appleName:String
    # apple AppleTaste
    appleTaste:String
}
# Apple Query
type Query{
    # query to get all apples
    findAllApple:[Apple]
}

\src\main\resources\application.properties

spring.graphql.graphiql.enabled=true

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>
    <name>spring boot graphql</name>
    <description>implementing graphql in spring boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <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>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>
    <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

query FindAllApple {
    findAllApple {
        appId
        appleId
        appleName
        appleTaste
    }
}

follow us on