SpringBoot GraphQL Schema Interface are Abstract Types that just defines the Generics Schema without implementations, a concrete class will provide all the Implementations. GraphQL also provides an Abstract Type Interface, which defines all the fields and is implemented by Concrete Types.
GraphQL Interface Type can be extended by other Interface Types or implemented by Object Type.
All the implementing Types must contain the same files defined by the Interface Type and further provide additional fields as per requirements.
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 interface Apple {
public int getAppleId();
public String getAppleName();
public Boolean getAvailable();
}
package org.wesome.graphql.entity;
public enum AppleEnum {
MACINTOSH, FUJI
}
package org.wesome.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
@AllArgsConstructor
public final class AppleVO {
private String appleName;
private Boolean available;
private AppleEnum appleType;
}
package org.wesome.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
@AllArgsConstructor
public final class Fuji implements Apple {
private int appleId;
private String appleName;
private Boolean available;
}
package org.wesome.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
@AllArgsConstructor
public final class Macintosh implements Apple {
private int appleId;
private String appleName;
private Boolean available;
}
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.AppleEnum;
import org.wesome.graphql.entity.AppleVO;
import org.wesome.graphql.entity.Fuji;
import org.wesome.graphql.entity.Macintosh;
import java.util.ArrayList;
import java.util.List;
@Service
public class AppleServiceImpl implements AppleService {
private static final List<Apple> apples = new ArrayList<>(List.of(new Macintosh(1, "Macintosh A", true), new Macintosh(2, "Macintosh B", false), new Fuji(3, "Fuji A", true), new Fuji(4, "Fuji B", false)));
@Override
public List<Apple> findAllApple() {
return apples;
}
@Override
public Apple addApple(AppleVO appleVO) {
Apple apple = null;
if (appleVO.getAppleType() == AppleEnum.FUJI) {
apple = new Fuji(apples.size() + 1, appleVO.getAppleName(), appleVO.getAvailable());
} else if (appleVO.getAppleType() == AppleEnum.MACINTOSH) {
apple = new Macintosh(apples.size() + 1, appleVO.getAppleName(), appleVO.getAvailable());
}
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
# Apple Enumeration
enum AppleEnum {
MACINTOSH, FUJI
}
# Fruit Interface
interface Apple{
# primary key of apple
appleId:ID!
}
# Apple Object
type Macintosh implements Apple{
# primary key of apple
appleId:ID!
# available Boolean
available:Boolean
# apple Name
appleName:String
}
# Apple Object
type Fuji implements Apple{
# primary key of apple
appleId:ID!
# available Boolean
available:Boolean
# apple Name
appleName:String
}
# Apple Input Object
input AppleVO{
# # primary key of apple
# appleId:ID!
# available Boolean
available:Boolean
# apple Name
appleName:String
# apple Name Enumeration
appleType:AppleEnum
}
# Apple Query
type Query{
# query to get all apples
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
<?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.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</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 Postman, in the query section add the below query
query FindAllApple {
findAllApple {
appleId
__typename
... on Fuji {
appleId
available
appleName
}
... on Macintosh {
appleId
available
appleName
}
}
}For Mutation, use the below query
mutation AddApple {
addApple(
appleVO: {
available: true
appleName: "a"
vendor: { vendorName: "Vendor A", available: false }
}
) {
appleId
available
appleName
vendor {
vendorId
vendorName
available
}
}
}