In this article, i am going to how to create two microservices and expose them through Netflix Zuul Proxy. Here i will show you step by step guide on setting up the Zuul proxy and routing the client requests to the related microservices.
What is Zuul and importance of reverse proxy?
Zuul is an api gateway (or rather Reverse Proxy) comes under the Netflix OSS stack. If you want to know the importance of reverse proxy in microservices architecture or know about Zuul, Please click here to refer my article on that. It is recommended to go through that article, before moving forward with this article.
Source Code
The fully source code related to this article can be found at GitHub. Click here to get it.
Setting up Microservices
In order to demonstrate the capabilities of Zuul proxy, i will set up two spring boot applications as microservices.
- student-service
- course-service
For the simplicity of this article, i will just post only the important code segments of above micorservices here. If you want to go thorough full application code, please get the source from the GitHub.
Important: First of all, i need to emphasize that all the REST endpoints are not properly implemented and they just contain few hardcoded values. The purpose of this article is to demonstrate the capabilities of the Zuul proxy in the context of Routing. If your real project implementation, you can follow the best practices and standards to implement the controller logic as your wish. Here i have just set up few controllers and RESTFul endpoints for the demonstration purpose.
student-service
Lets look at the StudentControlller.
The REST endpoints exposed in the StudentController can be listed as below.
#getting the name of the controller
GET http://localhost:8081/name
#getting the student by student Id
GET http://localhost:8081/students/{student_id}
#getting a list of students by course id
GET http://localhost:8081/courses/{course_id}/students
#getting a list of students who are registered for a particular course in the particular department.
GET http://localhost:8081/departments/{department_id}/courses/{course_id}/students
You can see that the REST endpoints contains simple URI Path (Resource Path) to some complex URI path with set of path variables. I have added those endpoints intentionally to show you how to map the routes for the those endpoints in Zuul Proxy.
The student-service can be up and run with following command. It will run on port 8081.
mvn spring-boot:run
course-service
Lets look at the CourseController
The REST endpoints exposed in the CourseController can be listed as below.
#getting the all courses
GET http://localhost:8082/courses
#getting the course by course_id
GET http://localhost:8081/courses/{course_id}
The course-service can be up and run with following command. It will run on port 8082.
mvn spring-boot:run
Setting up the Zuul Proxy
I know that most people are curiously waited until i start this section of the article. and lets start it now.
How to create the Zuul Proxy?
Just believe me that Zuul proxy is just another spring boot application. It has the Spring Cloud Netflix Zuul on its classpath dependencies and annotated the main SpringBootApplication configuration class with @EnableZuulProxy annotation.
Lets create our Zuul Proxy application.
Go to https://start.spring.io/ and generate a Spring Boot Application with dependency Zuul. Please refer the below screen shot.

Then open the generated project and annotate the main spring boot application configuration with @EnableZuulProxy annotation.
Lets change the port of the Zuul Proxy application into any port that is not in use. Here i will change it to 7070.
The Zuul Proxy can be up and run with following command.
mvn spring-boot:run
Route mapping with Zuul.
We have set up two microservices in our local server. one is running on port 8081 and other one is running on port 8082. We need to expose those two microservices through the Zuul proxy running on port 7070. These route mapping can be done in the application.properties file in the Zuul Proxy Application.
Lets look at how the REST endpoints in the student-service will be exposed through the Zuul proxy.
1. URI resource mapping for http://localhost:8081/name (No Path Variable)
zuul.routes.website-name.url = http://localhost:8081/name
Here you can see that it is a simple URI mapping. There is no path variable associated with it. According to the above route mapping, it will consider the website-name as the default route mapping. Therefore any request for the /website-name will be redirected to the http://localhost:8081/name.
e.g:- http://localhost:7070/website-name SEND TO http://localhost:8081/name
Since there is no path mapping, the path will be considered as “website-name”

2. URI resource mapping for http://localhost:8081/students/{student_id}
You can notice that there is a path variable exists in the URI resource path. Therefore we need to do the “path” mapping too.
zuul.routes.students.path = /students/*
zuul.routes.students.url = http://localhost:8081/students
According to the above route mapping, any request for the /students/* will be directed to http://localhost:8081/students. (This is applicable for any request that matches the above pattern)
Therefore http://localhost:7070/students/1 will be directed to http://localhost:8081/students/1

3. URI resource mapping for http://localhost:8081/courses/{course_id}/students
zuul.routes.students-courses.path = /courses/*/students
zuul.routes.students-courses.url = http://localhost:8081/courses
According to the above mapping any request that matches the /courses/*/students pattern will be directed to the url declared along with path variables.
The request for http://localhost:7070/courses/1/students will be directed to the http://localhost:8081/courses/1/students.
I know that now you are confused and thinking of why the URL path doest not start with /students-courses? It is the name that we have used to declare the URL (zuul.routes.students-courses.url).
Keep it in your mind that if there is a path declared in the application.properties file, that path will be considered. If there is no path declared, then it will consider the name defined in the url mapping as the path. (This is the default behavior)

4. http://localhost:8081/departments/{department_id}/courses/{course_id}/students
Here you can see that there are two path variables are available.
zuul.routes.department-courses-students.path = /departments/*/courses/*/students
zuul.routes.department-courses-students.url = http://localhost:8081/departments
Any request that matches the /departments//courses//students pattern, will be redirected to the endpoint http://localhost:8081/departments//courses//students URL along with path variables.
e.g:- http://localhost:7070/departments/1/courses/2/students WILL BE DIRECTED TO http://localhost:8081/departments/1/courses/2/students

Now we have completed the route mapping for all the REST services published in the student-service. Now lets look at how the REST endpoints in the course-service will be exposed through the Zuul proxy.
In the course-service, there are only two REST endpoints. we can do just one simple mapping for both of those endpoints.
# zuul route mapping for the course-service
zuul.routes.courses.url = http://localhost:8082/courses
According to the above route mapping, any request for the /courses will be directed to the http://localhost:8082/courses url
http://localhost:7070/courses will forward to http://localhost:8082/courses

http://localhost:7070/courses/1 will forward to http://localhost:8082/courses/1

In this article, i have guided you on exposing the micro services with through Zuul Proxy with Simple URI resource mapping (no path variables) to some complex URI resource mapping (with multiple path variables)
If you want to learn more about Spring Cloud Zuul Proxy, please click following link to visit the official documentation.
Click here to visit the Spring Cloud Documentation on Routing and Filtering with Zuul