Organising the interactions between different services in a modern microservices architecture can be challenging. The Zuul proxy, a gateway service that manages every request and performs dynamic routing for a microservice based applications.
Zuul is an edge service that offers security, resilience, monitoring, and dynamic routing. It is made to manage all of the routing and filtering required in a microservices architecture and is a component of the Netflix OSS (Open Source Software) stack.
We start by initializing a spring boot project along with the spring-cloud-starter-netflix-zuul dependency. The dependency in the pom.xml should be like the below:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
Next we enable the Zuul proxy with the help of @EnableZuulProxy annotation in the main class.
@SpringBootApplication
@EnableZuulProxy
public class ZuulProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulProxyApplication.class, args);
}
}
Finally, we configure the zuul routes in our application.properties file.
zuul.routes.service1.path=/service1/**
zuul.routes.service1.url=http://localhost:8081
zuul.routes.service2.path=/service2/**
zuul.routes.service2.url=http://localhost:8082
Requests from /service1/** and /service2/** are routed to http://localhost:8081 and 8082, respectively, with this configuration.
Assuming we have two microservices running on different ports:
localhost:8081
with an endpoint /hello
localhost:8082
with an endpoint /world
With Zuul configured as above, you can access these services through the Zuul proxy:
http://localhost:8080/service1/hello
will be routed to http://localhost:8081/hello
http://localhost:8080/service2/world
will be routed to http://localhost:8082/world
Zuul supports filters that can be used for various purposes like authentication, logging, etc. Here’s how we can add a filter:
@Component
public class SimpleFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
return null;
}
}
With the above filter implemented, let’s assume a client makes a GET request to http://localhost:8080/service1/hello, then we would get an output like the below:
GET request to http://localhost:8080/service1/hello