GraphQL does not fail the API response because of an error and tries to return a partial response. it usually helps in showing the response of the web page or API but while testing, errors should be prominently highlighted. to validate the errors, GraphQL Response Inerface provides an errors and verify method, that will assert the exception.
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("apples")
public List<Apple> apples() {
System.out.println("AppleControllerGraphQl.apples");
return appleService.findAllApple();
}
}
package org.wesome.graphql.data;
public enum AppleName {
MACINTOSH("Macintosh"),
FUJI("Fuji"),
GALA("Gala"),
JONAGOLD("Jonagold");
private String appleName;
AppleName(String appleName) {
this.appleName = appleName;
}
}
package org.wesome.graphql.entity;
public record Apple(int appleId, String appleName, Float price, Boolean available, String time) {
}
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wesome.graphql.entity.Apple;
import java.util.List;
import static org.wesome.graphql.GraphqlProjectApplication.apples;
@Service
public class AppleServiceImpl implements AppleService {
@Autowired
private Faker faker;
@Override
public List<Apple> findAllApple() {
return apples;
}
}
package org.wesome.graphql;
import com.github.javafaker.Faker;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.wesome.graphql.data.AppleName;
import org.wesome.graphql.entity.Apple;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@SpringBootApplication
public class GraphqlProjectApplication implements CommandLineRunner {
public static List<Apple> apples;
public static void main(String[] args) {
SpringApplication.run(GraphqlProjectApplication.class, args);
}
@Bean
public Faker getFaker() {
Faker faker = new Faker();
return faker;
}
@Override
public void run(String... args) {
Faker faker = new Faker();
apples = IntStream.rangeClosed(0, AppleName.values().length - 1).mapToObj(app -> new Apple(app, AppleName.values()[app].name(), Float.valueOf(app), faker.random().nextBoolean(), LocalTime.now().toString())).collect(Collectors.toList());
}
}\src\main\resources\application.properties
spring.graphql.graphiql.enabled=true\src\main\resources\graphql\schema.graphqls
# Apple Object
type Apple{
# primary key of apple
appleId:ID!
# apple Name
appleName:String
# apple price
price:Float
# apple Availability
available:Boolean
# current time
time:String
}
# Apple Query
type Query{
# query to get all apples
apples:[Apple]
}
<?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.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-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>\src\test\resources\graphql-test\apples.graphql
query Apples {
apples {
appleId
appleName
price
available
time
}
}
package org.wesome.graphql.controllers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.wesome.graphql.entity.Apple;
import java.util.Arrays;
import static org.wesome.graphql.GraphqlProjectApplication.apples;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AppleGraphQLControllerErrorVerifyTest {
@Autowired
HttpGraphQlTester graphQlTester;
@Test
void usingTester() {
Apple[] appleResponse = graphQlTester
.documentName("apples")
.execute()
.errors()
.verify()
.path("apples")
.entity(Apple[].class).get();
Assertions.assertEquals(appleResponse.length, apples.size());
Arrays.stream(appleResponse).forEach(System.out::println);
}
}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 Apples {
apples {
appleId
appleName
price
available
time
}
}