Building GraphQL Gateway With Springboot Framework

Joaquín Alfaro
The Startup
Published in
4 min readJan 18, 2021

This article shows the development of a simple GraphQL gateway in Java using Springboot framework to expose Rest services as GraphQL to simplify the access to resources from the frontend.

GraphQL

GraphQL is a query language for APIs defined by Facebook to solve some issues of traditional REST APIs as flexibility and simplicity.

All the resources of the API are exposed in a single request — normally a POST to /graphql — and the content is a query using GraphQL specification. The query specifies the filter and the data to be returned by the API.

In addition to queries, GraphQL provides Mutation for requests of creation, update and delete resources and Subscription for realtime queries.

Architecture of the solution

In microservices architectures it is mainly used REST to expose resources and API Gateways to consolidate them to be consumed from the frontend

The usage of GraphQL in the frontend means to change the protocol on the microservices to expose GraphQL, to avoid it we will create a Gateway to map REST definitions — Swagger spec. — to GraphQL

The below image shows the architecture of the solution proposed:

Architecture

Rest services are registered in the Gateway, the Gateway maps the service with GraphQL type and resolves the queries with the corresponding Rest service.

The solution is composed by the following pieces:

graphql-registry to register Rest services in the GraphQL gateway — it works as as a service discovery -

graphql-schema maps the Swagger spec. of the Rest service to GraphQL

graphql-resolver resolves GraphQL queries with the corresponding rest service.

graphql-server exposes the /graphql endpoint

How it works

Registration of services

Service registration
  1. The rest-service requests to graphql-registry the registration in the gateway
  2. graphql-registry calls to graphql-schema to add the rest-service to the GraphQL schema
  3. graphql-schema requests to the rest-service the Swagger spec. and maps it with GraphQL spec.

Solving queries

Solving GraphQL queries
  1. front-end requests a query to the graphql-server
  2. graphql-server uses graphql-schema to solve the query with requests to the corresponding rest-service

Mapping Rest/Swagger to GraphQL

The main part of the gateway is the mapping of Swagger with GraphQL

Table below shows the mapping between the elements of Swagger and GraphQL

Swagger mapping

Procedure used to map Swagger paths with GraphQL query fields:

Implementation

Stack of development

Java as programming language.

Springboot as framework.

graphql-java as implementation of GraphQL for java

maven for dependency management

Springboot project

graphql-gateway-server is the boot module that exposes /graphql endpoint for queries and /registry to register rest services

graphql-server implements /graphql endpoint and executes GraphQL requests

graphql-schema implements the mapping of Swagger specs. with GraphQL

graphql-registry implements /registry endpoint to register, unregister and list rest services in the gateway

Register service rest-countries-service with swagger url http://localhost:8082/v2/api-docs
curl POST 'http://localhost:8080/registry' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "rest-countries-service",
"url": "http://localhost:8082/v2/api-docs"
}'
Unregister service rest-countries-service
curl DELETE 'http://localhost:8080/registry?service=rest-countries-service'
Lists registered services
curl GET 'http://localhost:8080/registry'

graphql-registry-client implements the annotation GraphQLRegistryService to register rest services during startup.

For more details please check the README and code in https://github.com/joaquin-alfaro/graphql-gateway

Usage

Setup of rest services

  1. Adds dependency with graphql-registry-client
<dependency>
<groupId>org.formentor</groupId>
<artifactId>graphql-registry-client</artifactId>
<version>${graphql-gateway.version}</version>
</dependency>

2. Annotate the springboot main class with GraphQLRegistryService to register the service during startup

@SpringBootApplication
@GraphQLRegistryService
public class BooksApplication {
public static void main(String[] args) {
SpringApplication.run(BooksApplication.class, args);
}
}

3. Configure the host of the graphql-gateway-server in application.yaml

graphql:
registry:
uri: http://localhost:8080

Start GraphQL gateway

java -jar graphql-gateway-server/target/graphql-gateway.jar

Example

The project in https://github.com/joaquin-alfaro/graphql-gateway includes two Springboot samples to test graphql-gateway

rest-books-services that includes the operations GET /books and /books/{id}

rest-countries-services that includes the operations GET /countries and /countries/{id}

  1. Build the project
mvn clean package

2. Start graphql-gateway-server in port 8080

java -jar graphql-gateway-server/target/graphql-gateway.jar

3. Start rest-countries-services in port 8082

java -jar rest-countries-service/target/*.jar

List registered services calling http://localhost:8080/registry and check that rest-countries-service appears

4. Launch queries to GraphQL gateway in http://localhost:8080/graphql

query {
countries {
iso
name
cities {
name
id
}
}
}
GraphQL queries vs Rest request

Resources and references

Repository in github

https://github.com/joaquin-alfaro/graphql-gateway

graphql-java

https://www.graphql-java.com/

GraphQL Playground

https://github.com/graphql/graphql-playground

--

--