Search Tutorials


Spring Cloud Tutorial - Spring Cloud Gateway Hello World Example | JavaInUse



Spring Cloud Tutorial - Spring Cloud Gateway Hello World Example

In a previous tutorial we had implemented API Gateway using Netflix Zuul Component. However Zuul is a blocking API. A blocking gateway api makes use of as many threads as the number of incoming requests. So this approach is more resource intensive. If no threads are available to process incoming request then the request has to wait in queue.
In this tutorial we will be implementing API Gateway using Spring Cloud Gateway. Spring Cloud Gateway is a non blocking API. When using non blocking API, a thread is always available to process the incoming request. These request are then processed asynchronously in the background and once completed the response is returned. So no incoming request never gets blocked when using Spring Cloud Gateway.
We will first look at what is API gateway and why are they needed. Then we will be exploring the Spring Cloud Gateway Architecture and implement an API Gateway using it.

Spring Cloud - Table Of Contents

Microservice Registration and Discovery with Spring cloud using Netflix Eureka- Part 1. Microservice Registration and Discovery with Spring cloud using Netflix Eureka - Part 2. Microservice Registration and Discovery with Spring cloud using Netflix Eureka - Part 3. Microservice Registration and Discovery with Spring cloud using Netflix Eureka - Part 4. Spring Cloud- Netflix Eureka + Ribbon Simple Example Spring Cloud- Netflix Eureka + Ribbon + Hystrix Fallback Simple Example Spring Cloud- Netflix Hystrix Circuit Breaker Simple Example Spring Cloud- Netflix Feign REST Client Simple Example Spring Cloud- Netflix Zuul +Eureka Simple Example Spring Cloud Config Server using Native Mode Simple Example Spring Cloud Config Server Using Git Simple Example Spring Boot Admin Simple Example Spring Cloud Stream Tutorial - Publish Message to RabbitMQ Simple Example Spring Cloud Stream Tutorial - Consume Message from RabbitMQ Simple Example Spring Cloud Tutorial - Publish Events Using Spring Cloud Bus Spring Cloud Tutorial - Stream Processing Using Spring Cloud Data Flow Spring Cloud Tutorial - Distributed Log Tracing using Sleuth and Zipkin Example Spring Cloud Tutorial - Spring Cloud Gateway Hello World Example Spring Cloud Tutorial - Spring Cloud Gateway Filters Example Spring Cloud Tutorial - Spring Cloud Gateway + Netflix Eureka Example Spring Cloud Tutorial - Spring Cloud Gateway + Netflix Eureka + Netflix Hystrix Example

Video

This tutorial is explained in the below Youtube Video.

What is an API Gateway? Why do we need it?

An API Gateway acts as a single entry point for a collection of microservices. Any external client cannot access the microservices directly but can access them only through the application gateway
In a real world scenario an external client can be any one of the three-
  • Mobile Application
  • Desktop Application
  • External Services or third party Apps

spring cloud gateway tutorial

The advantages of this approach are as follows-
  • This improves the security of the microservices as we limit the access of external calls to all our services.
  • The cross cutting concerns like authentication, monitoring/metrics, and resiliency will be needed to be implemented only in the API Gateway as all our calls will be routed through it.
  • The client does not know about the internal architecture of our microservices system. Client will not be able to determine the location of the microservice instances.
  • Simplifies client interaction as he will need to access only a single service for all the requirements.

Spring Cloud Gateway Architecture

Spring Cloud Gateway is API Gateway implementation by Spring Cloud team on top of Spring reactive ecosystem. It consists of the following building blocks-
  • Route: Route the basic building block of the gateway. It consists of
    • ID
    • destination URI
    • Collection of predicates and a collection of filters
  • A route is matched if aggregate predicate is true.
  • Predicate: This is similar to Java 8 Function Predicate. Using this functionality we can match HTTP request, such as headers , url, cookies or parameters.
  • Filter: These are instances Spring Framework GatewayFilter. Using this we can modify the request or response as per the requirement. We will be looking at filters in detail in the next tutorial - Spring Cloud Tutorial - Spring Cloud Gateway Filters Example

spring cloud gateway architecture
When the client makes a request to the Spring Cloud Gateway, the Gateway Handler Mapping first checks if the request matches a route. This matching is done using the predicates. If it matches the predicate then the request is sent to the filters.

Implementing Spring Cloud Gateway

Using Spring Cloud Gateway we can create routes in either of the two ways -
  • Use java based configuration to programmatically create routes
  • Use property based configuration(i.e application.properties or application.yml) to create routes.
In this tutorial we will be implementing Spring Cloud Gateway using both configurations.
We will be implementing Spring Cloud Gateway application which routes request to two other microservices depending on the url pattern.
spring cloud gateway

Implement First Microservice

The Maven project will be as follows-
spring cloud first microservice
The pom.xml will be as follows-
<?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 http://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.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javainuse</groupId>
	<artifactId>first-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

</project>
Define the application.yml as follows-
spring:
  application:
    name: first-service
server:
  port: 8081
Create a Controller class that exposes the GET REST service as follows-
package com.javainuse.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/employee")
public class FirstController {

	@GetMapping("/message")
	public String test() {
		return "Hello JavaInUse Called in First Service";
	}
}

Create the bootstrap class with the @SpringBootApplication annotation
package com.javainuse;

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

@SpringBootApplication
public class FirstApplication {

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

}


Implement Second Microservice

The Maven project will be as follows-
spring cloud second microservice
The pom.xml will be as follows-
<?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 http://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.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javainuse</groupId>
	<artifactId>second-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

</project>
Define the application.properties as follows-
spring:
  application:
    name: second-service
server:
  port: 8082
Create a Controller class that exposes the GET REST service as follows-
package com.javainuse.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/consumer")
public class SecondController {

	@GetMapping("/message")
	public String test() {
		return "Hello JavaInUse Called in Second Service";
	}

}
Create the bootstrap class with the @SpringBootApplication annotation
package com.javainuse;

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

@SpringBootApplication
public class SecondApplication {

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

Implement Spring Cloud Gateway using property based config

The Maven project will be as follows-
spring cloud gateway microservice

The pom.xml will be as follows-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javainuse</groupId>
	<artifactId>cloud-gateway-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>gateway-service</name>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
		</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>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
Define the application.yml as follows-
server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
      - id: employeeModule
        uri: http://localhost:8081/
        predicates:
        - Path=/employee/**
      - id: consumerModule
        uri: http://localhost:8082/
        predicates:
        - Path=/consumer/**
Create the bootstrap class with the @SpringBootApplication annotation
package com.javainuse;

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

@SpringBootApplication
public class APIGatewayApplication {

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

}

Start the three microservices we have developed-
  • Go to url - localhost:8080/employee/message
    spring cloud gateway API tutorial
  • Go to url - localhost:8080/consumer/message
    spring cloud gateway example

Implement Spring Cloud Gateway using Java based config

The Maven project will be as follows-
spring cloud gateway config microservice

The pom.xml will be as follows-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javainuse</groupId>
	<artifactId>cloud-gateway-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>gateway-service</name>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
		</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>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
Define the application.yml as follows-
server:
  port: 8080
Create the configuration class where we define the route configurations. Gateway Handler resolves route configurations by using RouteLocator Bean.
package com.javainuse.config;

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

@Configuration
public class SpringCloudConfig {

    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/employee/**")
                        .uri("http://localhost:8081/")
                        .id("employeeModule"))

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

}
Create the bootstrap class with the @SpringBootApplication annotation
package com.javainuse;

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

@SpringBootApplication
public class APIGatewayApplication {

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

}

Start the three microservices we have developed-
  • Go to url - localhost:8080/employee/message
    spring cloud gateway API tutorial
  • Go to url - localhost:8080/consumer/message
    spring cloud gateway example

Download Source Code

Download it -
Spring Boot First Microservice
Spring Boot Second Microservice
Spring Cloud Gateway Microservice using Property based Config
Spring Cloud Gateway Microservice using Java based Config

See Also

Spring Boot Hello World Application- Create simple controller and jsp view using Maven Spring Boot Tutorial-Spring Data JPA Spring Boot + Simple Security Configuration Pagination using Spring Boot Simple Example Spring Boot + ActiveMQ Hello world Example Spring Boot + Swagger Example Hello World Example Spring Boot + Swagger- Understanding the various Swagger Annotations Spring Boot Main Menu Spring Boot Interview Questions