This session is about one of the more advanced pieces of our microservice architecture. I am talking about our Gateway Service. Our gateway service will be powered by the mighty ZUUL (see the picture for reference — if you not aware of it til now: It’s a Ghostbusters reference).

Zuul the Gatekeeper of Gozer

Zuul will be the gatekeeper of our architecture. We plan to use him to accept and pass requests to the microservices behind him. Of course, such a gateway can not only forward but also modify or reject requests. The gateway we are implementing will protect the services in the back by requesting basic auth credentials before allowing access to the downstream services.

Summoning Zuul

The start of our ceremony, we will be again on http://start.spring.io. “Start DOT spring DOT io” - But be careful: Saying it repeatedly may as well summon Josh Long. Author of a book I can’t recommend enough and his talks about the Spring Boot ecosystem are just superb! Yeah, but I think we shouldn’t get carried away too much, here the steps to initialize the gateway service :

For my projects I have chosen: Spring Boot 1.5.13

Group: com.marcuseisele.springboot_microservices

Artifact: gatewayservice

Artifact: gatewayservice Select Zuul, Actuator, Eureka Discovery and Security as dependencies.

Hit generate and move the content of the downloaded zip to the place where the services from the previous sessions are placed

Create a DockerFile for the new service and add it to docker compose (like in the previous sessions, see DockerFile / docker-compose)

Add the service to the pom file in the root directory (click to see the diff on github in case you have trouble)

After all this the gateway-service is a proper part of the project and will get build by running mvn package from the root of our project and it will also get started when we boot up all our services with docker using docker-compose up .

Taming Zuul

The service as we generated it is not doing much, we need to configure it properly first. The following steps will be necessary:

Enable the ZuulProxy for our gateway application

Create a general config for our gateway service

Setup a route for our counter-service

Enable handling Basic Authentication (remember? We wanted to have that)

After we have done all that: The gateway will be able to access our service-registry and based on these informations it will expose the service at the route we created.

Making Zuul our servant:

The first step is quickly done: Just add @EnableZuulProxy on top of the GatewayApplication -class. After that, go into the application.properties in order to setup the general configuration of Zuul. I personally started with the following:

server.port=9999

zuul.prefix=/api

eureka.client.serviceUrl.defaultZone=http://registryservice:8761/eureka

spring.application.name=zuul

If you were following the tutorial until now you may be confused by the eureka.client.serviceUrl.defaultZone here. It is something I did for refactoring the whole docker setup. It tells that the registry will be found at this network address which is by default exposed by docker-compose. So this configuration will just run in docker. If you want to use everything locally just remove that line here. In the future I may provide different profiles for running inside a docker container or running locally.

If we now would start the service there wouldn’t be much happening wouldn’t it? It would! Zuul is by default creating routes for all services a registry knows.

By default it is exposing them at a route matching the service name. So our counterService would be exposed at /api/counterservice (/api because we defined the Zuul-Prefix) which is not too bad, even tough I would love to have a more snappy name for that route. You could try it by accessing http://localhost:9999/api/counterservice/get to try it out. The main problem here is not the sub-optimal route name, but this configuration is also exposing all our other services, e.g. the configuration service and our registry. This is nothing we should be doing! It is leaking sensible information.

Let’s fix that!

This is done by adding following lines to our config:

zuul.ignored-services=*

zuul.routes.test.path=/cs/**

zuul.routes.test.serviceId=counterservice

The “test” part here is a part you can name like you want. I just named it test to make that obvious, it makes sense to have a proper name there for easier understanding what we are dealing with, but technically it is not necessary.

After this change we now only have one working route which is accessible via

http://localhost:9999/api/cs/ . You can access the functionallity of our counter-services at http://localhost:9999/api/cs/get .

So far so good, what is left now? Ah right, we wanted to add some Protection for our services. We will be using the SpringBoot-Starter spring-boot-starter-security , gladly we already added it to our dependencies when using the generator.

This now is more now an practical exercise of the following Spring Guide: https://spring.io/guides/gs/securing-web/. If you want to learn more about Spring Security make sure to head there. Spring Guides are a really valuable source for quickly learning how things work within Spring.

Let’s cut to the chase:

Create a class inside your main-package (or any subpackage). I called mine SecurityConfig .

Example SecurityConfiguration

Yes the credentials are hard-coded, make sure to don’t form a habit based on this code here 😅

What happens now when we run our services and access our counter-service using our gateway at ahttp://localhost:9999/api/cs/get . Yay! We get a password prompt from our browser which expects us to enter the credentials given in the SecurityConfig (user: mo password: password).

Quick Recap:

Not only about this article here but also about the whole series. What did we build until now? We have a counter-service which is representing our services doing the business logic, a configuration-service which provides configuration to that service. On top of that we have a registry which is keeping track of all services we have up and running. Now we created a service gateway which exposes and protects our services.

How cool is that? I mean we started from scratch and now have, I would say, a really good basis for a scaling architecture of microservices.

Outlook:

When you have a look at my github repository for this project (you should!), you may see that I adjusted a lot for making the services work inside their docker containers. The major adjustment was to change the used URLs to the ones provided by docker compose. The hostnames provided by docker compose are matching the container names. I will probably write something about these changes in the near future. In case this causes any confusion and you are not able to figure it out just let me know.

Having now a look at the previous sessions and our initial goal, I think we are almost there. The only last service missing is our Admin Service which is some kind of dashboard to monitor our services and give us insight into how they are performing.

I really hope you enjoyed this whole journey until now. If you do spread the word and give me a few claps, if don’t let me know! You can easily contact me here using direct message, via twitter.

If your journey with my tutorials started just here, make sure to also check out the other parts of this series which start at:

Implementing a Microservice Architecture with Spring Boot: Intro

Would love to hear your feedback!

If you want to be kept up to date about my latest posts (also on my personal blog https://programmerfriend.com) make sure to subscribe to mailing.