API Gateway using Spring Boot & Zuul (Part 1)

Nepal Brothers
4 min readMar 2, 2019

--

This blog is a part of building scalable Spring Boot microservices based project. It comprises of creating connecting microservices using Zuul, service discovery using Consul, security using Spring Security, distributed session using Spring Session and products such as MongoDB, Redis. Here is the chronological sequence of how I wrote article. https://medium.com/@nepalBrothers/web-development-scalable-web-app-using-spring-boot-and-spring-cloud-1f9960e1d61a

Code:

API Gateway is a concept of having a single point of entry to access all of the services in the backend.

So, when any device wants to access resources from the server, they make a call to the API-Gateway. API-Gateway then reaches out to rest of the services which actually take care of serving the user with what they need.

To demonstrate this, we will create a Zuul based API-Gateway in Spring Boot. We then will use API Gateway to make a call to the Microservice, namely Product Service.

Before doing anything, lets plan how to use Api-Gateway:

  1. API Gateway will run in port 8090
  2. Product will run in port 8080
  3. API Gateway will be configured to redirect all the traffic to the Product service.

Product Service

You can find the code about Product Service in Github:

We don’t need to make any changes in the above repo.

Lets implement API Gateway

We will use Zuul to implement API Gateway. Like in any of my other projects, lets generate dependencies through Spring Initializer.

We will need following dependencies:

  1. Web (So we can test some end points)
  2. Zuul (API Gateway)

Annotate Application with EnableZuulProxy

Annotating the SpringBootApplication with EnableZuulProxy will configure our application to consider the application as ZuulProxy.

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.cloud.netflix.zuul.EnableZuulProxy

@SpringBootApplication
@EnableZuulProxy
class ApiGatewayApplication

Add configuration in bootstrap.yaml file

We will now need to configure how to set up the proxy.

zuul:
routes:
product:
path: /product/**
url: http://localhost:8080
stripPrefix: true

By saying that, we are saying Zuul to

  1. route the /product/** path to the product service
  2. product url is http://localhost:8080
  3. When sending the request, strip the /product in the path. For instance, if API Gateway recieves /product/productId request, only the productId goes through.

Add port number in the application.yml configuration file

Since these are application level properties, we chose to use application.yml to set the configuration.

spring:
application:
name: apiGateway
server:
port: 8090

This is pretty self explanatory. We are telling Spring Boot to consider the name of this app as API Gateway and run it in 8090 port.

Lets run & then test

We can use maven from their root directory or use the help of IDE to do it for us. If it is maven:

Go to the root of Product application and run

mvn spring-boot:run

Do the same for the API Gateway as well from API Gateway’s root directory:

mvn spring-boot:run

Our API Gateway runs in localhost:8090 so lets hit that:

http://localhost:8090/product

Browser hitting the /product endpoint of our API Gateway

Awesome! We can see that /product is proxied to the Product Service.

Zuul filter runs before and after traffic reaches to upstream services

Zuul has this concept of filters that intercept the request/response

  • before sending it to upstream services and
  • receiving them from the services.
  1. Pre Filters act to the request before the request is sent to the downstream services. Pre Filters can be anything you design. It can be a component that logs the request received by the server, or it can also be implemented to use blacklist some users who violated the website rules, or it could be implemented to add additional values before passing request to downstream services.
  2. Post Filters act to the response after they come from the downstream services. It could be used to strip down headers we don’t want to send to the users, or logging the response that were received from the downstream.

Lets implement Zuul Filter that prints the request

Classes set with @Component will be taken care by Spring Boot for dependency injection.

Let it run again and lets make a call tohttp://localhost:8090/product and check the logs. We can see in the logs that the above Filter has run.

Things get more complex when we add more components on them. For instance,

  1. Some of the microservices only serve authenticated users.
  2. Some of the microservices serve any traffic.
  3. What if we want our API Gateway to handle authentication as well?

Next, we will equip our API Gateway with handling user session, passing session downstream to the microservices as well as handling user authentication.

I have written part 2 here:

--

--