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 3650
it 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
}
}