You are here
Home > API Gateway >

How To Implement Spring Cloud Gateway In Microservices

How To Implement Spring Cloud Gateway In MicroservicesMicroservices architecture offers us to deploy multiple services in different servers(hosts) in a private network. When a client request comes to microservices, it should get authenticated before the processing of request. Suppose we have 100 different services in a microservices based application. If client wants to interact with all of them, it will have to pass authentication 100 times. Reducing these many number of calls is one of the reasons to learn ‘How To Implement Spring Cloud Gateway In Microservices’.

If we have one service which takes care of authentication and also forward the request to concerned service, clients can get the response faster. Yes! We have such type of service which is responsible to do the same. It is nothing but Spring Cloud Gateway API. In other words, it acts as a mediator between client & service, that’s why called a Gateway. Apart from these tasks, what else it can do, we will discuss in the subsequent sections. Therefore, in this article we will discuss on ‘How To Implement Spring Cloud Gateway In Microservices’.

Table of Contents (Click on links below to navigate)

What is Spring Cloud Gateway?

Spring Cloud Gateway is a starter project provided by Spring Cloud. It provides an API Gateway built on top of the Spring Ecosystem, including: Spring 5.x, Spring Boot 2.x, Spring WebFlux and Project Reactor. Spring Cloud Gateway targets to offer 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 works on the Netty server provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container like Tomcat. Therefore, when we start a Spring Boot Gateway application, it automatically starts with Netty server.

What is an API Gateway?

An API Gateway is a single entry & exit point to multiple microservices for an external application/client. Sometimes it is also called Edge Microservice. Since external clients are restricted to access the microservices directly, it acts as a mediator between external clients & the collection of microservices. In a real world scenario an external client could be: Desktop application, Mobile Application, Any third party app, External services etc.

Why do we need an API Gateway?

In a Microservice based Application, the different services are generally deployed on the different hosts/servers. In this case client needs to remember the host & port of the service for the interaction which is very tedious and also there are chances of security breach. Hence, API Gateway validates the authentication, uses its intelligence & routes the client request to the appropriate service to process accordingly. Apart from the security & routing, it helps in monitoring/metrics, and resiliency.

What are the advantages of an API Gateway?

1) External clients don’t need to pass through the authentication of each & every microservice. External client only needs to pass authentication of only one microservice at the beginning which is the API Gateway. If authentication gets rejected at API Gateway, the request will not proceed further to any other microservice. Therefore, it improves the security of the microservices as we limit the access of external calls to all our services.

2) We don’t need to expose the endpoints of microservices to the external application/client.

3) It provides an abstraction between microservices and the clients. 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.

4) Since all client requests route through the API Gateway, we need to implement the cross cutting concerns like authentication, monitoring/metrics, and resiliency only in the API Gateway. In this way, it helps in minimizing development effort.

5) Needless to say, the API Gateway makes client interaction easy because it works as a single entry & exit point for all the requests.

What are the disadvantages of an API Gateway?

1) Since every request goes through API Gateway after a security check, it may slow down the performance.

2) Suppose we implement only one API gateway for the multiple microservices & if API Gateway fails, the request will not be processed further. Hence, we should implement multiple Gateways and manage the traffic via load balancer.

3) Sometimes we need to implement Gateway specific front-end. For example, we have three Different front-end such as Android client, iOS client, Web Client. All three may require some special APIs & configuration to work properly. To overcome this situation, we may require to create multiple types of API Gateways like one for each type of client. Some people call this pattern as ‘Back-end for Front-end’.

What are the terminologies used in API Gateway?

Generally, there are three basic terminologies used in the API Gateway: Route, Predicate, Filter

Route

The Route is a basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true. Basically, it represents the URL to which incoming request to be forwarded.

Predicate

The Predicate is nothing much more than a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters. In a nutshell, it contains the condition which should match to forward the incoming request to a particular Route URL.

Filter

These are instances of GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request. In simple words, it offers us a provision to modify the incoming request before or after sending it to the Route URL.

What is Routing in API Gateway?

It is a process of identifying a Microservice based on the predicate and URL(Path) and execute it. Generally, there are two types of Routing: Static Routing and Dynamic Routing

Static Routing 

If a microservice has a single instance(also known as a direct call to microservice) is known as static routing. In this case API Gateway routes the request directly to the microservice.

Dynamic Routing 

Dynamic Routing comes into the picture when a microservice has multiple instances. In this case, API Gateway reaches Eureka, to get less load factor instance and then routes the request to the corresponding microservice. It internally generates Feign Client code based on the given configuration for load balancing.

How to Include Spring Cloud Gateway in your Project?

In order to implement the functionalities of Spring Cloud Gateway in your project, make use of the starter ‘Gateway’ in case of STS. You may also include Gateway dependency in your pom.xml as below.

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

How to disable Spring Cloud Gateway from your Project?

If you include the starter, but you do not want the gateway to be enabled due to any reason, set below property in your application.properties file.

spring.cloud.gateway.enabled=false

Or else, comment the dependency of gateway starter in your pom.xml file.

How To Implement Spring Cloud Gateway In Microservices?

In order to implement the Spring Cloud Gateway in Microservices project, let’s assume a use case where we have 2 microservices, Eureka server and a Gateway Service. Please note that Gateway service is itself a microservice.

Details of the Use case 

Let’s assume we have 2 microservices: Order Service & Payment Service. Apart from that we will have a Gateway Service. Needless to say, in order to register & discover aforesaid microservices, we will have one Eureka Server. Please note that Gateway service must also be registered with the Eureka server in order to access other microservices details. We will also test the load balancing feature of API Gateway in case there are multiple instances of a particular service. Let’s start implementing our use case step by step.

Create Microservice #1(Eureka Server)

In order to discover and communicate Microservices with each other, we need to  create a Eureka Server Service. Creating a Eureka Server is itself similar to creating a Microservice. Moreover, it is just a Spring Boot Project that incorporates Spring Cloud’s Eureka Server dependency. In application.properties file we will have some specific properties that will indicate that this application/microservice is a Eureka server. In order to create Eureka Server follow the below steps.

Step #1: Create a Spring Boot Project

Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. If you are new to Spring Boot, visit Internal Link to create a sample project in spring boot. While creating a project in STS, add starter ‘Eureka Server’ in order to get features of it.

Step #2: Apply Annotation @EnableEurekaServer at the main class

In order to make your application/microservice acts as Eureka server, you need to apply @EnableEurekaServer at the main class of your application.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaServerApplication {

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

Step #3: Modify application.properties file

Add below properties in your application.properties file.

server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

Create Microservice #2(Payment Service)

In our case, Product Service is an example of a microservice. Moreover, the product service will publish the REST endpoints. Let’s develop it step by step.

Step #1: Create a Spring Boot Project

Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. While creating a project in STS, add starter ‘Eureka Discovery Client’, ‘Spring Web’ in order to get all required features.

Step #2: Apply Annotation @EnableEurekaClient at the main class

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class SpringCloudFeignBookServiceApplication {

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

Step #3: Modify application.properties file

Add below properties in your application.properties file.

server.port=9009
#ServiceId
spring.application.name=PAYMENT-SERVICE
#Publish Application(Register with Eureka)
eureka.client.service-url.default-zone=http://localhost:8761/eureka
# instance id for eureka server
eureka.instance.instance-id=${spring.application.name}:${random.value}

Moreover, ‘eureka.client.service-url.default-zone=http://localhost:8761/eureka’ indicates that this service is getting registered with the Eureka Server.

Step #4: Create a RestContoller class as PaymentRestController.java

In order to publish Payment Service, we will create a PaymentRestController and define the endpoints as below. Please note that, here we are not using a database as our focus is on API Gateway functionality. Instead, we are using some hardcoded values just to illustrate an example wherever required.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/payment")
public class PaymentRestController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/info")
    public ResponseEntity<String> showPaymentInfo() {
       return ResponseEntity.ok("FROM PAYMENT SERVICE, Port# is: " + port);
    }
}

Create Microservice #3(Order Service)

In our case, Order Service is an example of a microservice. Moreover, the order service will publish the REST endpoints. Let’s develop it step by step.

Step #1: Create a Spring Boot Project

Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. While creating a project in STS, add starter ‘Eureka Discovery Client’, ‘Spring Web’ in order to get all required features.

Step #2: Apply Annotation @EnableEurekaClient at the main class

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class SpringCloudFeignBookServiceApplication {

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

Step #3: Modify application.properties file

Add below properties in your application.properties file.

#port number
server.port=9560
# serviceId
spring.application.name=ORDER-SERVICE
# Eureka location
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
# instance id for eureka server
eureka.instance.instance-id=${spring.application.name}:${random.value}

Moreover, ‘eureka.client.service-url.default-zone=http://localhost:8761/eureka’ indicates that this service is getting registered with the Eureka Server.

Step #4: Create a RestContoller class as OrderRestController.java

In order to publish Payment Service, we will create a PaymentRestController and define the endpoints as below. Please note that, here we are not using a database as our focus is on API Gateway functionality. Instead, we are using some hardcoded values just to illustrate an example wherever required.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderRestController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/info")
    public ResponseEntity<String> showOrderInfo() {
       return ResponseEntity.ok("FROM ORDER SERVICE, Port# is: " + port);
    }
}

Create Microservice #4(API Gateway Service)

This is one of the most important services for our use case. Let’s develop it step by step.

Step #1: Create a Spring Boot Project

Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. If you are new to Spring Boot, visit Internal Link to create a sample project in spring boot. While creating a project in STS, add starter ‘Eureka Discovery Client’, ‘Gateway’, ‘Spring Reactive Web’ in order to get all required features.

Step #2: Apply Annotation @EnableEurekaClient at the main class

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class SpringCloudFeignBookServiceApplication {

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

Step #3: Modify application.properties file

Add below properties in your application.properties file.

server.port=8080
spring.application.name=GATEWAY-SERVICE
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

Moreover, ‘eureka.client.service-url.default-zone=http://localhost:8761/eureka’ indicates that this service is getting registered with the Eureka Server.

Step #4: Create a Configuration class as SpringCloudGatewayRouting.java

This is the most important class for our implementation. It incorporates the configuration code for API Gateway as below.

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 SpringCloudGatewayRouting {

    @Bean
    public RouteLocator configureRoute(RouteLocatorBuilder builder) {
       return builder.routes()
      .route("paymentId", r->r.path("/payment/**").uri("http://localhost:9009")) //static routing
      .route("orderId", r->r.path("/order/**").uri("lb://ORDER-SERVICE")) //dynamic routing
      .build();
    }
}

Please note that there will be one route configuration per microservice as shown above. It is clear from the code that payment service has only one instance so direct URL is provided. On the other hand, Order service has multiple instances, hence load balancing is applied.

How to test API Gateway Enabled Microservice?

It’s time to test our API Gateway enabled Microservice. Please follow below steps:

1) Start Service/Application containing Eureka Server

2) Start Payment Application

3) Start Order Application, change the port number in application.properties and start the application again to create a second instance of it. Repeat the process to create third instance if you want and so on.

4) Start the API Gateway service. Observe that Netty server will be started rather than Tomcat.
5) Open a browser window, hit below URLs and observe the results.

http://localhost:8080/payment/info
http://localhost:8080/order/info

If you are getting expected results, it means you are calling microservices from API Gateway and your implementation is correct.

Conclusion

After going through all the theoretical & example part of ‘How to Implement Spring Cloud Gateway in Microservices’, finally, we should be able to implement API Gateway in Microservices. Similarly, we expect from you to further extend these examples and implement them in your project accordingly. In addition, If there is any update in the future, we will also update the article accordingly. Moreover, Feel free to provide your comments in the comments section below.

close

One thought on “How To Implement Spring Cloud Gateway In Microservices

Leave a Reply

Top