How to build Spring Cloud Gateway for Microservices

In this tutorial we will build Spring Cloud Gateway for Microservices built using Spring Boot framework. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs. When it receives request, Spring Cloud Gateway forwards it to a Gateway Handler Mapping, which determines what should be done with requests matching a specific route.

Spring Cloud gateway is based on API Gateway Pattern. So we will see what is API Gateway Pattern and how it solves problems.

API Gateway Pattern

Let’s say you are building an online store that uses Microservices Architectural Pattern and you are developing a product details page, which needs to be developed in multiple versions of user interfaces (UI) for rendering on different devices, such as, mobile(android/iphone), tab, desktop/laptop. Now you may develop web application or expose REST APIs to be accessible by client applications or third party applications.

A product details page on UI usually displays a lot of information about a product:

Basic information about the product, such as, name, overview, price, etc.
Purchase history of the product
Availability of the product
Buying options
Other products or items that are frequently bought with this product
Other products or items bought by customers who bought this product
Customer reviews
Seller ratings

Since your online store uses Microservices Architectural Pattern, the product details data are spread over multiple services. So you need to develop different service APIs for your product details page. For example,

A service about the basic product information, such as, name, overview, price
A service about product price
A service about the purchase history of the product
A service about the availability of the product
A service about customer reviews on the product
A service about the seller ranking

Now the problem is how do the clients of microservice based applications access the individual service?

The following key points are the force which your clients need to maitain to interact with the service APIs:

Microservices generally provides fine-grained APIs or small services with single resposibilities, so clients need to interact with multiple services. Therefore, for the above example, where you are developing product details page, a client needs to interact with multiple such services.

Diffrent kind of UIs or clients need different data. For example, desktop version UI may have more details about product than mobile version UI.

Network performance is different in different kind of UIs or clients. Desktop may have faster performance than mobile version.

The number of service instances and their locations change dynamically.

Service may use diverse set of protocols and some of them may not be web friendly.

In the above points we have seen how clients interact with the service APIs even if service APIs are often different than what clients need.

Therefore the solution would be to implement an API Gateway that is the single entry point for different kinds of clients. The API gateway handles requests that are simply proxied or routed to appropriate service. Or it may handle requests by fanning out to multiple services.

The API gateway may expose different API for each client rather than providing all-in-one-fit API. The API gateway may also implement security to verify whether the client is authorized to perform a particular request.

Benefits of API Gateway:

Clients are unknown how the application is partitioned into microservices
Clients are unknown about the determination of locations of the service instances
Provides the optimal API for each client
Reduces the roundtrips or requests for each client because API gateway enables clients retrive data from multiple service with single roundtrip. So it improves user experience.
Clients do not need to be bother about the protocols used by the internal services becuase API gateway provides web friendly protocol.

Drawbacks of API Gateway:

Increases complexity due to it’s also a moving part and you must develop, deploy and manage

API Gateway Implementation:

An event-driven/reactive approach is best if it scales to scale to handle high loads. On the JVM, NIO-based libraries such as Netty, Spring Reactor, etc. are used. NodeJS is another option.

Zuul vs Spring Cloud Gateway

You may be wondering why we are switching to Spring Cloud Gateway instead of keep going with Zuul.

The principal reason is Zuul 1.x is blocking and if you need better performance by moving to reactive pattern (non-blocking) from your Microservices using Spring Boot 2 with Reactor then you need Spring Cloud Gateway.

Now Zuul 2.x has support for non-blocking with netty but Spring does not have built-in support for Zuul 2.x and you need to run your service with Zuul separately.

Related Posts:

Prerequisites

Eclipse 2019-12, Java at least 1.8, Spring Boot 2.2.6, Spring Cloud, Microservices using Spring Boot and Cloud

Create Projects

As we are going to use existing microservices projects we had created earlier, so we will create the project for Spring Cloud Gateway.

Create a project in Eclipse called spring-cloud-gateway.

The build.gradle script can be given with the following configurations:

buildscript {
	ext {
		springBootVersion = '2.2.6.RELEASE'
	}
    repositories {
    	mavenLocal()
    	mavenCentral()
    }
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id "io.spring.dependency-management" version "1.0.9.RELEASE"
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
    
sourceCompatibility = 12
targetCompatibility = 12

repositories {
	mavenLocal()
    mavenCentral()
}

dependencies {
	implementation("org.springframework.cloud:spring-cloud-starter")
	implementation("org.springframework.cloud:spring-cloud-starter-gateway")
}

dependencyManagement {
    imports {
        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR3'
    }
}

Routing

The Spring Cloud Gateway uses routes in order to process requests to downstream services.

Spring Cloud Gateway supports two forms of routing: Java (using RouteLocator) and configuration files (application.properties/yaml).

We will create here configuration file – src/main/resources/application.yml file to configure routing.

server:
   port: 9090
   
spring:
   cloud:
       gateway:
           routes:
            - id: currency-conversion-service
              uri: http://localhost:9100/
              predicates:
               - Path=/cc-converter/**
              filters:
               - RewritePath=/cc-converter/from/(?<from>.*)/to/(?<to>.*)/quantity/(?<quantity>.*), /currency-converter/from/$\{from}/to/$\{to}/quantity/$\{quantity}
            - id: forex-service
              uri: http://localhost:9000/, http://localhost:9001/
              predicates:
               - Path=/fx-exchange/**
              filters:
               - RewritePath=/fx-exchange/from/(?<from>.*)/to/(?<to>.*), /forex-exchange/from/$\{from}/to/$\{to}

There are three main building blocks for Spring Cloud Gateway:

Route: The primary API of the gateway and think of it as a destination where we want a particular request to route to. It comprises of an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.

Predicate: Java 8 Function Predicate. It enables to match on anything from the HTTP request, such as headers or parameters. This is literally a condition to match. i.e. kind of “if” condition. For example, if requests has something, e.g., path=/foo or request header contains foo-bar etc.

Filter: Standard Spring Framework’s WebFilter, where requests and responses can be modified before or after sending the downstream request. You can also create your own filter with your own logic.

RewritePath filter to rewrite the request path from /cc-converter/** to /currency-converter/** or /fx-exchange/** to /forex-exchange/**

Now you see how internal path is hidden from clients.

Create Main Class

Now we will create a main class that will start our application on port 9090.

package com.roytuts.spring.cloud.gateway;

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

@SpringBootApplication
public class SpringCloudGatewayApp {

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

}

Deploy Applications

Make sure you deploy all microservices followed by Spring Cloud Gateway application.

So deploy your applications in the order – eureka-server-config, currency-conversion-service, two instances of forex-service, finally spring-cloud-gateway.

Testing the Application

The below youtube video shows the output using REST client when we interact with the Microservices using the Spring Cloud Gateway.

Hope you got an idea how to build Spring Cloud Gateway. We have many features on Spring Cloud Gateway and we can explore them as and when required.

Download

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *