This is complete step by step Tutorial on how to implement Microservice Architecture with the Zuul API Gateway and Eureka Service Discovery
- Introduction to API Gateway
- How the Zuul API Gateway Works
- Our Architecture
- Build the Eureka Server
- Build the Product Server
- Build the Zuul API Gateway
- Build the Product Web and Test!
1. Introduction to API Gateway
As you already know, in a microservices architecture, the microservices would have to register with a Service Registry such as Eureka Server. We implemented this here.
In this way, when a consumer or client wants to access a service, it would have to get to the registry. The registry would then find the required service. The registry contains mappings of routes to the internal microservices
Sometimes, however, you may want some microservices to be directly accessible from the outside by clients. This is where an API gateway can be used. So a set of microservices could be exposed to consumers from the outside using an API gateway while the rest of the services could remain unexposed. The API gateway is the channel through which the clients can access publicly exposed microservices.

2. How the Zuul API Gateway Works
From he figure, you can see that all the microservice are registered with Eureka Server. However, for microservices that have to be accessible from the outside, they are bound to the API gateway also.
Then, the API gateway itself should be addressable from the addressable from the outside. For apps, they also have to be accessible from the outside since client devices have to connect directly to them.
3. Our Architecture
Let’s now understand the architecture we would use in this tutorial. This is shown in the Figure below

- User visits the product.html page in the Angular UI app and the page displays in the user’s browser. This page contains markup to to display products data.
- Once the product.html page is loaded, it will make a request to the ProductWeb microservice.
- This request directly routes to the ProductWeb API as the ProductWeb is not bound to the API gateway
- The ProductWeb microservice has to delegates this request to the ProductServer. To achieve that, the ProductWeb would then route the request to the API gateway
- The API Gateway is registered with the Eureka Server. So the API gateway will do a service registry lookup in the Eureka Server to find the ProductServer. Once found, the ProductServer location details is returned to the Ribbon client which is part of ProductWeb
- The ProductWeb microservice takes this informaiton and load balances the request to any of the instances of the ProductServer using RestTemplate.
Let’s Code the four microservices one after another. The ProductServer and the Angular UI app would be the same as in the Eureka Demo we did previously. Anyway our architecture would consists of four services
4. Build the EurekaServer(eureka-server)
Just a web application that has the Eureka Discovery Server and Spring Web dependencies. Runs on port 8761. Also it remember to disable register-with-eureka and fetch-registry. Finally, do add the @EnableEurekaServer to the main application class.
Here’s he content of the application.properties file:
server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false
5. Build the ProductServer(product-server:8080):
We would add the following dependencies: Spring Web, Lombok, Eureka Discovery Client, H2 and Spring Data Jpa.
This server would store a list of products in H2 Database. The ProductServer will contain the following files in addition to the ProductServerApplication.java:
- Product.java: This is the model file and
- ProductRepository.java: An interface that extend the JpaRepository
- ProductController.java: RestController that exposes the /products and /products/{productId} endpoints
- InitializationComponent.java: A component that contains the @PostConstruct annotated method to load the initial data.
6. ApiGateWay(api-gateway)
This would be the actual Zuul API Gateway which is also a microservice. Additionally, is is also a Eureka client and therefore has to register with the Eureka Server
Contains the dependencies: Spring Web, Eureka Discovery Client and Zuul Proxy.
You need to add the @EnableEurekaClient and the @EnableZuulProxy annotation to the main application class.
I would like us to use a yaml file for the configuration. We would placed the configuration in the application.properties but I want you to learn something new.
So create new file in the resources folder and name it application.yml. In this file we would tell Zuul the following:
- the url routes to allows
- the location of the Eureka Server
- the we also provide application name and port
Here below is the complete content of the application.yml file
spring: application: name: api-gateway server: port: 8082 zuul: routes: product-api: path: /api/** service-id: product-server eureka: client: service-url: defaulZone: http://localhost:8761/eureka hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2000
From the yaml file, you can see that any URL that has the pattern /api/** coming into Zuul would be routed to the product-server
7. Build the ProductWeb(product-web)
The dependencies include: Rest Repositories, Eureka Discovery Client, Lombok and Spring Web.
Of course, you need to add the @EnableEurekaClient.
Now, this microservice would have the following files:
Product.java: the normal POJO class
ProductService.java: an interface that exposes two methods
ProductRestController.java: this class implements the two methods defined in the ProductService. However, note now that in the controller, the url to use would be that of the API gateway. And like before, RestTemplate would be used for the request.
Finally, the content of the application.properties file is given below:
server.port=8081 spring.application.name=product-web eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
Now you can fire up the application and do some testing. I recommend you watch the video for clarification