GraphQL is a query and manipulation language tool for APIs and is agnostic of underlying server architecture. Spring Boot supports HTTP and HTTPS protocols. Spring Boot GraphQL with HTTPS protocol provides an additional encryption layer to secure the data transfer and secure the communication between server and client.
HTTPS (Hypertext Transfer Protocol Secure) is a combination of basic HTTP (Hypertext Transfer Protocol) with the SSL/TLS (Secure Socket Layer/Transport Layer Security) protocol. Sometimes API requires sending sensitive data such as login credentials, bank details, credit card details, etc.
How to create a SSL Certificate
Java provides keytool in jdk\bin folder, execute the below command.
keytool -genkeypair -dname "cn=wesome, ou=wesome, o=wesome.org, c=India" -alias wesome -storetype PKCS12 -keyalg RSA -keypass wesome -keysize 2048 -keystore keystore.p12 -storepass wesome -validity 3650it will create a keystore.p12 file, copy the file, and paste it into the root directory of the project.
Let's see an example of Spring Boot GraphQL with HTTPS
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 record AppleGraphQLController(@Autowired AppleService appleService) {
@QueryMapping("findAllApple")
List<Apple> findAllApple() {
return appleService.findAllApple();
}
}
package org.wesome.graphql.data;
public enum AppleType {
MACINTOSH, FUJI, GALA, JONAGOLD
}
package org.wesome.graphql.entity;
public record Apple(int appleId, String appleName, Boolean available, Float price) {
}
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 org.springframework.stereotype.Service;
import org.wesome.graphql.data.AppleType;
import org.wesome.graphql.entity.Apple;
import java.util.ArrayList;
import java.util.List;
@Service
public record AppleServiceImpl() implements AppleService {
private static final List<Apple> apples = new ArrayList<>(List.of(new Apple(1, AppleType.MACINTOSH.name(), true, 1.1F), new Apple(2, AppleType.FUJI.name(), false, 2.2F), new Apple(3, AppleType.GALA.name(), true, 3.3F), new Apple(4, AppleType.JONAGOLD.name(), false, 4.4F)));
@Override
public List<Apple> findAllApple() {
return apples;
}
}
package org.wesome.graphql;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class GraphqlProjectApplication {
public static void main(String[] args) {
SpringApplication.run(GraphqlProjectApplication.class, args);
}
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}\src\main\resources\graphql\schema.graphqls
# Apple Object
type Apple{
# primary key of apple
appleId:ID!
# apple Name
appleName:String!
# apple availability
available: Boolean
# apple Price
price:Float
}
# Apple Query
type Query{
# query to get all apples
findAllApple:[Apple]
}\src\main\resources\application.properties
spring.graphql.graphiql.enabled=true
server.port=8443
security.require-ssl=true
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=wesome
server.ssl.key-store-type=PKCS12
server.ssl.keyAlias=wesome
<?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>how to access Rest API
cURL
cURL command is very useful for checking the API endpoint. The rest endpoint can be accessed via curl localhost:8080/findAllApple
how to access GraphQL API
GraphQL provides multiple ways to access the API, let's see them
cURL
The GraphQL can be accessed via the below cURL command.
curl --location 'http://localhost:8080/graphql' \
--header 'Content-Type: application/json' \
--data '{"query":"query FindAllApple {\r\n findAllApple {\r\n appleId\r\n appleName\r\n taste\r\n }\r\n}","variables":{}}'GraphiQL
GraphQL provides an inbuild UserInterface GraphiQL, which can be accessed via http://localhost:8080/graphiql, since it is HTTPS protocol, the browser will automatically redirect to https://localhost:8443/graphiql?path=/graphql in the query section add the below query
query FindAllApple {
findAllApple {
appleId
appleName
available
price
}
}Postman Post Method
GraphQL can be accessed via Postman as well, open Postman-> file-> import and paste the below curl
curl --location --request POST "https://localhost:8443/graphql" \
--header "Content-Type: application/json" \
--data "{\"query\":\"query FindAllApple {\n findAllApple {\n appleId\n appleName\n available\n price\n }\n}\",\"variables\":{}}"Postman GraphQL Request Type
Postman provides a GraphQL request type UI, Open Postman-> file-> new->GraphQL and add the URL https://localhost:8443/graphql in the query section add the below query
query FindAllApple {
findAllApple {
appleId
appleName
available
price
}
}