Spring Cloud Gateway: Architecture and its working

Reading Time: 4 minutes

Origin: why?

Everything happens for a reason in nature. And the world is changing perhaps the technology also changing with time, now we are using microservices instead of monoliths. Let’s discuss why we need Spring Cloud Gateway:

In Microservices, the different services need to communicate with each other to achieve inter-service communication. In case the clients need to hit the service for consuming the API, we have two choices:

  • First, to expose the address of all the microservices to the clients.
  • Second, create the gateway which helps to route the requests to various microservices and respond to the clients.

Here, creating the gateway is beneficial:

  • Don’t need to secure each and every microservice used.
  • Malicious threats would be taken care by itself such as cross-site scripting (xss) attacks.
  • Don’t need to configure the differents APIs.

Definition

Spring Cloud Gateway is a gateway that allows the library to premise the API gateways on top of Spring framework and Java. It allows routing the requests with flexibility and concerns about the numbers of the request calls. It provides security against malicious threats such as cross-cutting attacks.

Architecture

Spring Cloud Gateway utilizes a Netty server to allow non-blocking asynchronous request processing.

Let’s discuss some important components of the gateway:

Route: It behaves as the building block for the gateway that contains the URL helps to direct the requests to the destination. It consists of:

  • ID
  • destination URI
  • collection of predicates or collection of filters

Predicate: It is the building block used to set the criteria, which checks the incoming requests/calls. And then forward the requests to the specific microservice if the path is present within the requests. It refers to the Java 8 Function Predicate.

Filters: It is a building block where we can modify the incoming requests before sending the requests to the microservices or back to the client. It is an instance of Spring WebFilter.

The below diagram represents the architecture of Spring Cloud Gateway:

Working

Spring Cloud Gateway is a library used for building an API gateway. It is intended to exist in the middle of a requester and the requested resource, where it intercepts, analyzes and modifies every request based on their context.

The below diagram shows the overall working of the gateway:

Implementation of Spring Cloud Gateway

Here, creating the two different spring boot applications (acts as the two different microservices) and spring cloud gateway application. This gateway application acts as the gateway to these two microservices.

Microservice 1:

Let’s configure the first microservice, define the application.properties file, and create the rest controller for the spring boot application using the spring web dependency:

# application.properties file for first microservice
spring.application.name=microservice-one
server.port=8081
// Java Code
// First Microservice

package com.first.microservice.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/firstmicroservice")
public class FirstMicroserviceController {

    @GetMapping("/firstmessage")
    public String message() {
        return "Hello, welcome to the first microservice. ";
    }

}

Microservice 2:

Let’s configure the second microservice, define the application.properties file, and create the rest controller for the spring boot application using the spring web dependency:

# application.properties file for second microservice
spring.application.name=microservice-two
server.port=8082
// Java Code
// Second Microservice

package com.second.microservice.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/secondmicroservice")
public class SecondMicroserviceController {

    @GetMapping("/secondmessage")
    public String message() {
        return "Hello, welcome to the second microservice. ";
    }

}

Spring Cloud Gateway Configuration:

# application.properties file for spring cloud gateway 
spring.application.name=gateway
sever.port=8080
## microservices mapping ##
spring.cloud.gateway.routes[0].id=microservice-one
spring.cloud.gateway.routes[0].uri=http://localhost:8081/
spring.cloud.gateway.routes[0].predicates[0]=Path=/firstmicroservice/**
spring.cloud.gateway.routes[1].id=microservice-two
spring.cloud.gateway.routes[1].uri=http://localhost:8082/
spring.cloud.gateway.routes[1].predicates[0]=Path=/secondmicroservice/**
// Java code 
// Configuration class for spring cloud gateway
 
package com.spring.cloud.gateway.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayMicroservicesConfig {

    public RouteLocator gatewayConfig(RouteLocatorBuilder locatorBuilder) {

        return locatorBuilder.routes()
                .route(r -> r.path("/firstmicroservice/**")
                        .uri("http://localhost:8081/")
                )

                .route( r -> r.path("/secondmicroservice/**")
                        .uri("http://localhost:8082/")
                )
                .build();
    }

}
// Java Code
// Main spring boot Class for spring cloud gateway

package com.spring.cloud.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {

   public static void main(String[] args) {
      SpringApplication.run(GatewayApplication.class, args);
   }

}
<!-- pom.xml project dependency file for spring cloud gateway -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 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>2.5.10</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.spring.cloud</groupId>
 <artifactId>gateway</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>gateway</name>
 <description>Demo project for Spring Cloud Gateway</description>
 <properties>
  <java.version>11</java.version>
  <spring-cloud.version>2020.0.5</spring-cloud.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <dependencyManagement>
  <dependencies>
   <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud.version}</version>
    <type>pom</type>
    <scope>import</scope>
   </dependency>
  </dependencies>
 </dependencyManagement>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>

</project>

Benefits

  • Spring Cloud Gateway configuration works great for multilingual environments ( microservices written in different languages).
  • It is very useful for the developers as there in no external GUI needed to configure.
  • It is an open source and free to use.

References

For more detailed information about the Spring Cloud Gateway, kindly click here.