Zuul server is an application server that handles routing in a microservices architecture in Spring Boot applications. Zuul handles the dynamic routing of requests to specific microservices. Zuul is built to make it easier to route requests dynamically, monitor various services, and provide a single entry point for all requests, ensuring that all the requests are secure since it handles request filtering before routing to the specific service.
In this tutorial, we will build two services:-
Student service - This service will handle student-related requests and reports.
Course service - This service will handle course-related requests, i.e. creating courses, enrolling students, etc.
In addition to the above services, we will also have the following services:-
Zuul server service - This service will handle all the requests and routing to other services.
Eureka service - Through this service, other services will discover each other and be able to communicate with each other.
Prerequisites
For a better understanding of the concepts, we will be using the following resources:-
Knowledge in Spring Boot.
JDK 8 installed on your computer.
IDE of your choice installed on your computer. For this guide, I use IntelliJ IDEA.
Table of contents
Project Setup
Student Service
Navigate to spring initliazr on your web browser.
Input the project name as "StudentService".
Add
Eureka Discovery
,Spring Web
andLombok
as project dependencies.Click on the generate button to download the project-generated boilerplate code and dependencies as an archive file.
Unarchive the downloaded and open it in your favourite IDE.
Sync the project to download the dependencies from the central Maven repository.
Update the
StudentServiceApplication
class with the code snippet below.
@SpringBootApplication
@EnableDiscoveryClient
public class StudentServiceApplication {
public static void main(String[] args) {
SpringApplication.run(StudentServiceApplication.class, args);
}
}
@EnableDiscoveryClient
is used to enable the discovery client. This makes it possible for other services to discover and communicate with this service through the Eureka service.
Since this service will handle student information, we will create a Student
class to represent the student. So, in the root project directory, create a new Java class called Student
and add the code snippet below.
@Data
@Builder
@AllArgsConstructor
public class Student {
private final String name;
private final String regNo;
}
@Data
annotation is used to generate getters and setters for the fields. This cleans up our Student object, which would belong with the getters and setters included.@Builder
annotation is used to generate a builder class for the class. It makes it possible to use the builder pattern with this class while creating instance objects.@AllArgsConstructor
annotation is used to generate a constructor with all the fields.
We need to create a controller class for this service to handle the incoming HTTP requests. In the root project directory, create a new Java class called StudentController
and add the code snippet below.
@RestController
@RequestMapping("/api")
public class StudentController {
//Returns a list of students
@GetMapping("/students")
public ResponseEntity<List<Student>> test() {
return new ResponseEntity<>(returnStudentList(), HttpStatus.OK);
}
//Generates list of students
public List<Student> returnStudentList() {
List<Student> students = new ArrayList<>();
students.add(new Student("Peter Johnson", "ADM 112"));
students.add(new Student("Jim William", "ADF 112"));
students.add(new Student("Mercy Peterson", "ADK 112"));
return students;
}
}
@RestController
annotation generates a REST controller class, making it possible to handle HTTP requests.@RequestMapping("/api")
annotation is used to map the requests to the controller class.test()
method is used to handle the HTTP request to/api/students
, it returns a list of students from thereturnStudentList()
method in the response body.
To make this service discoverable, we need to configure the Eureka service URL, give a name to this service and set a port on which this service will be running. Add the following configurations in the application.yml
file.
server.port=8100 #port for the service
spring.application.name=student-service #name of the service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #eureka server url
Course Service
Navigate to spring initliazr on your web browser.
Input the project name as "CourseService".
Add
Eureka Discovery Client
,Spring Web
andLombok
as project dependencies.Click on the generate button to download the project-generated boilerplate code and dependencies as an archive file.
Unarchive the downloaded and open it in your favourite IDE.
Sync the project to download the dependencies from the central Maven repository.
Create a new Java class called
Course
and add the code snippet below.
@Data
@AllArgsConstructor
public class Course {
private final String name;
private final String id;
}
- This class will represent a course object.
In the root project directory, create a new Java class called CourseController
and add the code snippet below.
@RestController//Marks the as a REST controller
@RequestMapping("/api/course")//The base URL for the controller
public class CourseController {
//Function returns a list of courses
@GetMapping
public ResponseEntity<List<Course>> getCourses() {
return new ResponseEntity<>(getCourseList(), HttpStatus.OK);
}
//Function generates a list of courses
private List<Course> getCourseList() {
List<Course> courses = new ArrayList<>();
courses.add(new Course("Computer Science", "1"));
courses.add(new Course("Computer Engineering", "2"));
courses.add(new Course("Software Engineering", "3"));
return courses;
}
}
- This class handles all the incoming HTTP requests. The
getCourses()
method returns a list of courses from thegetCourseList()
method in the response body.
We now need to configure this service to enable it to be registered in the Eureka service. Add the following configurations to the application.properties
file.
server.port=8200 # The port for the service
spring.application.name=course-service # The name of the service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ # The URL of the eureka server
Zuul Service
Navigate to spring initliazr on your web browser.
Input the project name as "ZuulService".
Add
Eureka Server
as the project dependencies dependencies.Unarchive the downloaded and open it in your favourite IDE.
Add the dependency below to the
dependecies
section on thepom.xml
file.
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
Sync the project to download the dependencies from the central maven repository.
Update the
ZuulServerApplication
class with the code snippet below.
@SpringBootApplication
@EnableZuulProxy
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
@EnableZuulProxy
is used to enable the Zuul proxy. This makes it possible for the service to handle all the incoming requests and route them to the specific services discovered by the eureka server.
The Zuul server needs to communicate with the Eureka server to make it possible to route requests to the registered services. To configure the Zuul server, add the following configurations to the application.properties
file.
server.port=8050 # The port for the service
spring.application.name=zuul-edge-server # The name of the service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ # The URL of the eureka server
Sometimes the requests might fail to reach the Eureka server, this is because the Eureka server might not be running. To ensure the requests are routed to the correct services, we need to configure the Zuul server to retry the requests if the Eureka server is unavailable. Add the following configurations to the application.properties
file.
spring:
servlet:
multipart:
max-file-size: 1000MB
max-request-size: 1000MB
zuul:
host:
connect-timeout-millis: 10000
socket-timeout-millis: 60000
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 60000
Eureka Service
Navigate to spring initliazr on your web browser.
Input the project name as "EurekaService".
Add
Eureka Server
as the project dependencies.Click on the generate button to download the project-generated boilerplate code and dependencies as an archive file.
Unarchive the downloaded and open it in your favourite IDE.
Sync the project to download the dependencies from the central Maven repository.
Update the
EurekaServiceApplication
class with the following code.
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
@EnableEurekaServer
annotation is used to enable the eureka server. This makes it possible to register the services with the eureka server.
We finally need to configure the eureka server to make this service discoverable. Add the following configurations to the application.properties
file.
server.port=8761 # The port for the service
eureka.client.registerWithEureka=false # Disable registration with eureka
eureka.client.fetchRegistry=false # Disable fetching of registry from eureka server
eureka.server.waitTimeInMsWhenSyncEmpty=0 # Disable waiting for eureka server
Run the services and make an API call through the Zuul gateway to course service through http://localhost:8050/api/course/. We get the response shown below. We can make API requests to the course and student services through the Zuul service. This makes it easier to implement a filter and authorizations on the Zuul service to restrict data access based on user roles or authentication state.
[
{
"name":"Computer Science",
"id":1
},
{
"name":"Information Technology",
"id":2
}
]
Conclusion
Up to this point, we have covered the basics of deploying microservices using Spring Boot. Try challenging yourself by converting the monolith applications you have to a microservice architecture with Zuul as the API gateway. You will realise how applications built with microservices are much easier to maintain and scale.