Search code examples
spring-bootspring-cloudnetflixnetflix-zuul

Simple Reverse Proxy with Spring Boot and Netflix Zuul


I'm looking to implement a simple reverse proxy with Spring Boot that is:

  • Easy to add routes
  • Ability to add custom authentication on a per route basis
  • Add additional headers as needed

I've looked at the facilities provided by the @EnableZuulProxy annotation but it seems too heavyweight as I don't have a desire to use Eureka, Ribbon, or Hystrix. However, @EnableZuulServer is a bit light on configuration.

Would anyone be able to provide an example of what I'm after? Is Netflix Zuul the right choice for this or is there another library I should be looking at?

Thanks!


Solution

  • Simple Reverse Proxy Server

    It's easy to set up a simple proxy reverse using Spring Boot without Ribbon, Eureka, or Hystrix.

    Simply annotate your main application class with @EnableZuulProxy and set the following property in your configuration:

    ribbon.eureka.enabled=false
    

    Then define your routes in your configuration like such:

    zuul.routes.<route_name>.path=<route_path>    
    zuul.routes.<route_name>.url=http://<url_to_host>/
    

    where <route_name> is an arbitrary name for your route and <route_path> is a path using Ant-style path matching.

    So a concrete example would be something like this

    zuul.routes.userservice.path=users/**
    zuul.routes.userservice.url=http://localhost:9999/
    

    Custom Filters

    You can also implement your custom authentication and any additional headers by extending and implementing the ZuulFilter class and adding it as an @Bean to your @Configuration class.

    So another concrete example:

    public class MyFilter extends ZuulFilter {
    
      @Override
      public String filterType() {
        // can be pre, route, post, and error
        return "pre";
      }
    
      @Override
      public int filterOrder() {
        return 0;
      }
    
      @Override
      public boolean shouldFilter() {
        return true;
      }
    
      @Override
      public Object run() {
        // RequestContext is shared by all ZuulFilters
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
    
        // add custom headers
        ctx.addZuulRequestHeader("x-custom-header", "foobar");    
    
        // additional custom logic goes here
    
        // return isn't used in current impl, null is fine
        return null;
      }
    
    }
    

    and then

    @Configuration
    public class GatewayApplication {
    
      @Bean
      public MyFilter myFilter() {
        return new myFilter();
      }
    
    }