Configuring the API gateway

In previous sections, we saw how to define Zuul as an API gateway. In subsequent sections, we explored other Netflix components, such as Feign and Ribbon, to make RESTful calls for inter-service communication. However, the interaction that we created happened directly between services. Though we have configured an API gateway with Zuul, we have not used it as a central point of the request flow. In this section, we will make the necessary configuration changes so that every request passes through our API gateway.

The very first thing we will learn is to implement a custom filter and configure it to the API gateway to trace the request and print it in the log. For simplicity, we will capture a few details about the current request. Open the Spring Boot application that we created for Zuul and add a filter class as follows: 

@Component
public class CustomPreFilter extends ZuulFilter {
private static Logger _logger = LoggerFactory.getLogger(ZuulFilter.class);

@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
HttpServletRequest request = RequestContext.
getCurrentContext().getRequest();
_logger.info("********** REQUEST STARTED ******************");
_logger.info("Port :"+ request.getLocalPort());
_logger.info("HTTP Method :"+ request.getMethod());
return null;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
}

For any custom filter, you need to extend an abstract class, ZuulFilter, which is provided by Netflix. There are certain abstract methods that we need to provide the implementation, as follows: 

  • shouldFilter(): We apply this filter or not based on the return value of this method.
  • filterType(): As we have seen, Zuul supports various filters type such as pre, post, error, and so on. The pre filter will be executed after the request reaches Zuul and before it is routed to other microservices. Similarly, the post filter will be executed once the response returns from other microservices, and the error filter type will be triggered when an error happens in between.
  • filterOrder(): We can define as many filters as we want. This method defines their order of priority.
  • run(): This method is the placeholder where you can write your filter logic.

We use will another filter that will be triggered once the response comes back, filter type post, as follows:

@Component
public class CustomPostFilter extends ZuulFilter {
private static Logger _logger = LoggerFactory.getLogger(ZuulFilter.class);

@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
_logger.info("********* REQUEST ENDED *************");
return null;
}
@Override
public String filterType() {
return "post";
}
@Override
public int filterOrder() {
return 0;
}
}

Next, let's see how to access microservices through our API gateway. We have exposed a REST API for inventory-service as http://localhost:8793/api/inventory/get-inventory/3, and we will now update this URL to route the request from the API gateway. The pattern for the API gateway URL would be as follows:

http://<API_Gateway_Host>:<API_Gateway_Port>/{service-name}/{uri}

The Zuul API gateway will use the Eureka naming server to connect to the desired microservice. The service name in the previous pattern is the name (with the spring.application.name property in the application.properties or bootstrap.properties file) of the service registered in the Eureka naming server. The API gateway is accessible with http://localhost:8781, so to access the inventory-service URL with the API gateway, the new URL would be http://localhost:8781/inventory-service/api/inventory/get-inventory/3. You will get the request details in the Zuul log as follows:

o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms 
com.netflix.zuul.ZuulFilter : ******************* REQUEST STARTED ***********
com.netflix.zuul.ZuulFilter : Port :8781
com.netflix.zuul.ZuulFilter : HTTP Method :GET
.........
com.netflix.zuul.ZuulFilter : ******************* REQUEST ENDED *************

This is how we can trace the request with various filters with the Zuul API gateway. However, the call is forwarded from inventory-service to catalog-service with Feign, which is still bypassing the API gateway and making a direct call to the microservice. Now, let's see how to configure Feign so that the call is routed through the Zuul API gateway. The original Feign proxy was as follows: 

@FeignClient(name="catalog-service", path="/api/catalog")
@RibbonClient(name="catalog-service")
public interface CatalogServiceProxy {
...
}

The updated Feign proxy interface would be as follows:

@FeignClient(name="zuul-api-gateway", path="y/api/catalog")
@RibbonClient(name="catalog-service")
public interface CatalogServiceProxy {
....
}

The change happened in the service name of the @FeignClient annotation. Previously, it was directly pointing to catalog-service, but now it is pointing to the Zuul API gateway service. zuul-api-gateway is the name of the Zuul API gateway service defined with the spring.application.name property in the application.properties file. 

Run the URL again, and you will see the logs are printed twice. The loges are printed first, when the request reaches inventory-service, and second when the request is routed from inventory-service to catalog-service through Feign. This is how Zuul is configured to trace every request made across the microservices.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.12.240