Introducing Zuul

Zuul is an edge service created by Netflix that bases its functionality around filters. Zuul filters follow the interceptor filter pattern (as described at http://www.oracle.com/technetwork/java/interceptingfilter-142169.html). Using filters, you can perform a set of actions on HTTP requests and responses during their routing.

Zuul is the name of a gatekeeper that is taken from a movie (see http://ghostbusters.wikia.com/wiki/Zuul for more details), and represents exactly the functionality that this project has, namely that of a gatekeeper.

You can apply the filter during four phases, as shown in the following diagram:

Zuul filters

Let's review each one of these phases:

  • pre: Before the request is processed
  • route: During the routing of the request to the service
  • post: After the request has been processed
  • error: When an error occurs during the request

Using these phases, you can write your own filter to handle different requirements. Some common uses for filters during the pre phase are as follows:

  • Authentication
  • Authorization
  • Rate limits
  • Translation and transformation operations in the request body
  • Custom headers injection
  • Adapters

Some common uses of filters in the route phase are as follows:

  • Canary releases
  • Proxying

Once a request has been processed by the microservice, you have two scenarios:

  • Succesful processing
  • Error during the processing of the request 

If the request was successful, all the filters associated with the post phase will be executed. Some common uses of filters that are executed during this phase are as follows:

  • Translation and transformation operations in the response payload
  • Storing of metrics associated with the business itself

On the other hand, when errors occur during the processing of the requests, then all the error filters will be executed. Some common uses of filters in this phase are as follows:

  • Saving the associated metadata of requests
  • Removing technical details from the response for security reasons
The preceding points are just a few common uses of filters during each phase. Think about your own business when writing filters that target your needs.

In order to write a Zuul filter, the ZuulFilter class should be extended. This class has the following four abstract methods that needed to be implemented:

public abstract class ZuulFilter 
implements IZuulFilter, Comparable<ZuulFilter>
{
public abstract String filterType();
public abstract int filterOrder();
public abstract boolean shouldFilter();
public abstract Object run() throws ZuulException;
...

}

The two methods shown in bold are not directly declared in the ZuulFilter class, but are instead inherited from the IZuulFilter interface that is implemented by this class.

Let's review each one of these methods to understand how a Zuul filter works.

First, you have the filterType method, where you need to specify the phase in which you want to execute the current filter. The valid values of this method are as follows:

  • pre
  • post
  • route
  • error

You can write the preceding values by yourself, but it is better to use the FilterConstant class, as follows:

@Override
public String filterType()
{
return FilterConstants.PRE_TYPE;
}

All the phases are listed in the class that we mentioned previously:

public class FilterConstants 
{
...
public static final String ERROR_TYPE = "error";
public static final String POST_TYPE = "post";
public static final String PRE_TYPE = "pre";
public static final String ROUTE_TYPE = "route";
}

The filterOrder method is used to define the order in which the filter will be executed. It's common to have more than one filter in each phase, so by using this method, you can configure the desired order for each filter. The highest value represents a low order of execution.

It is easy to configure the execution order by using the org.springframework.core.Ordered interface, which has two values that can be used as references:

package org.springframework.core;
public interface Ordered
{
int HIGHEST_PRECEDENCE = -2147483648;
int LOWEST_PRECEDENCE = 2147483647;
...
}

The shouldFilter method is used to determine whether the filter logic should be executed or not. In this method, you can access the request information using the RequestContext class, as follows:

RequestContext ctx = RequestContext.getCurrentContext();
// do something with ctx

This method should return a boolean value that indicates whether the run method should be executed or not.

Finally, the run method contains the logic that's applied in the filter. In this method, you can also use the RequestContext class to perform the desired logic.

For example, let's use the endpoint implemented previously to query the movies screened by a cinema:

curl http://localhost:8701/cinemas-service/cinemas/1/movies

The following is a simple implementation to print the requested method and URL:

@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info("Requested Method: {}", request.getMethod());
log.info("Requested URL: {}", request.getRequestURL());
return null;
}

Once the request has been processed, you will have the following output:

PRE FILTER
Requested Method: GET
Requested URL: http://localhost:8701/cinemas-service/cinemas/1/movies
..................Content has been hidden....................

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