API Gateway with Spring Cloud

API Gateway with Spring Cloud

1 Comment

Using API Gateways is a common design pattern with microservice architectures. API Gateways allow you to abstract the underlying implementation of the microservices.

Microservices based systems typically have a large number of independent services. One challenge in such systems is how external clients interact with the services. If external clients interact directly with each microservices, we will soon end up with a mesh of interaction points. This is nothing but setting up the system for failure. The client has to be aware of each microservices location.

What happens:

  • If the location of one Microservice changes?
  • To the client if one new Microservice is added?
  • If a team decides to update the routes of a running Microservice?

Also, who is orchestrating the communication between the client and the microservices?

It is obvious that we cannot have such a tight coupling between client and microservices. We have to hide the services layer from the client and in steps the API Gateway pattern.

The API Gateway is primarily responsible for request routing. The Gateway intercepts all requests from clients. It then routes the requests to the appropriate microservice.

There are several API Gateway implementations. In this post, I will explain how to perform request routing with the Netflix Zuul Gateway.

The Application

We will create a Spring Boot multi-modular application for this post.

The multi-modular application contains two Spring Boot services: API Gateway Service and Message Service.

This is how the application looks in the Projects window of IntelliJ.
Mult-module Project Structure

You can find the project structure in the accompanied source code of this post on Github.

The API Gateway Service

The API Gateway Service is a Spring Boot application that routes client requests to the Message service.

As we will use Netflix Zuul as the API Gateway implementation, we first need to add the dependency of Netflix Zuul in the pom.xml file.

The code to add the Netflix Zuul dependency is:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  <version>2.2.6.RELEASE</version>
</dependency>

Next, we will refactor the ApigatewayServiceApplication main class to enable Zuul.

ApigatewayServiceApplication.java

@EnableZuulProxy
@SpringBootApplication
public class ApigatewayServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(ApigatewayServiceApplication.class, args);
	}
}

In this code, the @EnableZuulProxy annotation enables all the features of the Zull API Gateway. This makes the API Gateway Service a reverse proxy that will forward client requests to the Message Service.

Creating the application.properties File

Next, we will write the application.properties file for the API Gateway Service.

application.properties

server.port=8080
spring.application.name=apigateway
zuul.routes.message.url = http://localhost:8090

The zuul.routes.message.url property is of importance here. It specifies that if the URL contains message, the request should be routed to the application running on port 8090.

The Message Service

For our application, we have already created a RESTfull service named Message Service. It is a simple service with a single controller GET endpoint that returns a message.

The controller code is this.

GreetingController.java

package com.springframework.guru.controller;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/version1/")
class GreetingController {
    @GetMapping("message")
    public String getMessage() {
        return "Hello from REST API";
    }
}

Next, in the application.properties file, we specify the server port and the application name.

application.properties

server.port=8090
spring.application.name=message

This file defines two properties: the server.port property that is 8090 and the spring.application.name property specifies the name of the application as message.

Testing the API Gateway

To test the application, we need to first build and package the application.

In the Terminal window type the following command: mvn clean package

You can see that the Terminal window displays that the Microservices Pattern and its sub-modules are successfully built and packaged.

Terminal Window Displaying Build Status

We will now run both the API Gateway Service and Message Service applications.

You can see that the API Gateway Service is running on port 8080.
API Gateway Output

On the other hand, the Message Service is running on port 8090.

Message Service Output

Now, to test routing, we will use Postman.

  1.  In Postman, select GET from the drop-down list.
  2. Type the following URL : localhost:8080/message/api/version1/message
    In this URL, port 8080 is where the API Gateway is listening for requests. message is the route that we defined in the application.properties file of the API Gateway Service. Finally, api/version1/product is the endpoint mapping URL of GreetingController.
  3. Click the Send button. Postman displays the message returned by the Message Service through the API Gateway.

Request Response through Postman

The important thing to notice is that we are accessing the Message Service endpoint using the localhost:8080/message/api/version1/message URL instead of localhost:8080/api/version1/message

Here, message is indicating a route to the API Gateway that routes the request to the Message Service.

Summary

In a Microservices architecture, request routing is one of the many use cases of API Gateway. Another common use of API Gateway is load balancing between backend services.

One more important use case of API Gateway is Gateway Offloading. It is a common pattern to move shared and common functionalities from the backend services to the API Gateway. An example is the validation of authentication token, such as JWT token. Instead of validating a JWT token in each of your services, you offload it to the API Gateway.

API Gateway is also used to manage service releases, such as a Canary release. It is the responsibility of the API Gateway to gradually redirect requests to a newer version of a service until the newer version is ascertained to be stable.

You can find the source code of this post on Github.

For in-depth knowledge Microservices with Spring Cloud check my Udemy Best Seller Course Spring Boot Microservices with Spring Cloud Beginner to Guru

About SFG Contributor

Staff writer account for Spring Framework Guru

    You May Also Like

    One comment

    1. February 4, 2021 at 6:04 am

      Zuul is deprecated

      Reply

    Leave a Reply

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

    This site uses Akismet to reduce spam. Learn how your comment data is processed.