Spring Cloud Gateway is a lightweight, reactive API Gateway built on Spring WebFlux. It acts as a single entry point for multiple microservices, handling client requests and routing them to the appropriate service. It provides features such as routing, filtering, load balancing, security, rate limiting, and monitoring
- Provides dynamic routing based on request paths.
- Supports pre-filters and post-filters for request processing.
- Helps implement security, authentication, and authorization.
Spring Cloud Gateway Architecture
The main components of the spring cloud gateway are:

Route
- Defines how requests are routed.
- Contains Route ID, URI, Predicates, and Filters.
Predicate
- Evaluates incoming requests against conditions.
- If the condition matches, the request is routed to the target service.
Filter Chain
- Processes requests and responses.
- Performs tasks like logging, authentication, header modification, and request validation.
Request Flow
- Client sends request to Gateway.
- Gateway checks Route Predicates.
- Matching route is selected.
- Request passes through Pre-Filters.
- Request is forwarded to Microservice.
- Response passes through Post-Filters.
- Gateway returns response to the client
Spring Cloud Gateway – Step-by-Step Implementation
Step 1: Create the First Microservice
Create a new Spring Boot project named Microservice1 with the following configuration:
- Project: Maven
- Language: Java
- Packaging: Jar
- Java Version: 17
- Dependency: Spring Web
Include the below dependencies in the pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://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.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.microservice</groupId>
<artifactId>Microservice1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Microservice1</name>
<description>Demo project for 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-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>
Step 2: Configure Microservice 1
Add the following properties in application.properties:
spring.application.name=MicroService1
server.port=8081
Step 3: Create Controller for Microservice 1
Create a REST controller with endpoint:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/serviceA")
public class Controller {
@GetMapping("/displayMessage")
public ResponseEntity<String> showMessage(){
return ResponseEntity.ok("Microservice 1 controller executed");
}
}
Step 5: Create the Second Microservice
- Create another Spring Boot project named Microservice2.
- Dependencies: Spring Web
Step 6: Configure Microservice 2
Add the following properties:
spring.application.name=MicroService2
server.port=8082
Step 7: Create Controller for Microservice 2
Create an endpoint:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/serviceB")
public class Controller {
@GetMapping("/displayMessage")
public ResponseEntity<String> showMessage(){
return ResponseEntity.ok("Microservice 2 controller executed");
}
}
Now, we have both of our microservices reading and running on port numbers 8081 and 8082 respectively. Now let's create a Spring Cloud Gateway running at port 8083 and then we'll see whether both microservices can be accessed from port 8083 or not.
Spring Cloud Gateway Implementation
There are two ways to create an API gateway.
- Programmatic configuration: Here we create Spring Cloud Gateway as Java bean. The routes, predicates, and all are created as a traditional Java program.
- Property configuration: Here, we create components of Spring Cloud Gateway as properties in the application.properties or application.yml file.
Spring Cloud Gateway Implementation using Properties
Create a Separate Spring boot application to create a gateway. Include the following dependencies in the pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://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.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gateway</groupId>
<artifactId>Gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<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>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-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>
The project structure looks like
Now create a file with the name application.yml inside the resources folder and populate it with the following:
server:
port: 8083spring:
cloud:
gateway:
routes:- id: Microservice1
uri: http://localhost:8081/predicates:
- Path=/serviceA/**
- id: Microservice2
uri: http://localhost:8082/
predicates:
- Path=/serviceB/**
Spring Cloud Gateway Programmatic Implementation
here also, the project structure and dependencies remain the same. Also apart from port configuration, remove everything from the YML file. Now create a bean inside GatewayApplication.java class as follows:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator routerBuilder(RouteLocatorBuilder routeLocatorBuilder){
return routeLocatorBuilder.routes()
.route("Microservice1",r->r.path("/serviceA/**")
.uri("http://localhost:8081/"))
.route("Microservice2",r->r.path("/serviceB/**")
.uri("http://localhost:8082/")).build();
}
}
Now, on running the gateway application using any of the above methods, we can see that both microservices can be accessed with a single port as below