Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zuul route from root path

I have some microservices discovered with Eureka. Most of them provide some API. And I have "edge" service called "Gateway service" which is Zuul Proxy actually. The thing is that there is a web application. It was hosted by gateway service for a long time and there was not any problem with that. But right now I need to host this client on separate service behind gateway. It's not a problem. I created new service and put web application there. But the thing is that Zuul on gateway service have next configuration

zuul:
  ignoredServices: '*'
  prefix: /api
  sensitiveHeaders: Cookie, Set-Cookie
  routes:
    config-service:
      path: /conf/**
      serviceId: config-service
    security-service:
      path: /security/**
      serviceId: security-service
      stripPrefix: false
    request-service:
      path: /requests/**
      stripPrefix: false

I need to do so that user able to access web application from a root path like this http://app.com/. But right now I can access it only by http://app.com/api/ which is completely incorrect.

My task is:

  1. Make web app hosted on another service available from root path.
  2. It also very important that /api prefix remain for all other services.

I tried to implement ZuulFilter. But looks like it does nothing with root path and runs only when there is match with any routes described above.

How can I make this work?

UPDATE: I have a little success with ZuulFilter. I made it work. Here is configuration of Zuul:

zuul:
  ignoredServices: '*'
  sensitiveHeaders: Cookie, Set-Cookie
  routes:
    api: /api/**
    config-service:
      path: /conf/**
      serviceId: config-service
    security-service:
      path: /security/**
      serviceId: security-service
      stripPrefix: false
    request-service:
      path: /requests/**
      stripPrefix: false
    frontend-host-service:
      path: /**

And ZuulFilter itself

@Bean
    public ZuulFilter apiPrefixStrip(RouteLocator routeLocator) {
        return new ZuulFilter() {

            @Override
            public String filterType() {
                return "pre";
            }

            @Override
            public int filterOrder() {
                return 0;
            }

            @Override
            public boolean shouldFilter() {
                RequestContext context = RequestContext.getCurrentContext();
                return context.getRequest().getRequestURI().startsWith("/api");
            }

            @Override
            public Object run() {
                RequestContext context = RequestContext.getCurrentContext();
                String path = context.getRequest().getRequestURI();
                Route route = routeLocator.getMatchingRoute(path.substring(4));
                if (route != null) {
                    context.put("proxy",route.getId());
                    context.put("requestURI", route.getPath());
                    context.set("serviceId", route.getLocation());
                }
                return null;
            }
        };
    }

How this work: there is property zuul.routes.api=/api/** which does not do anything actually. It just allows to map all matched paths to Zuul filter chain (described in documentation). All other routes described here is set like there is no /api at all. It allows to reach services like this: http://app.com/requests e.g. for request service. The ZuulFilter performs check for every request described in properties but it runs only if the requested URI starts with /api and it redirects this request same way like there is no any /api in path.

It works really. But I still dont like this solution because there are endpoints without /api prefix still remain on gateway service. May be anybody knows how to improve it?

like image 739
Valeriy Maslov Avatar asked Jan 26 '17 14:01

Valeriy Maslov


People also ask

How does Zuul routing work?

Zuul is an edge service that proxies requests to multiple backing services. It provides a unified “front door” to your system, which allows a browser, mobile app, or other user interface to consume services from multiple hosts without managing cross-origin resource sharing (CORS) and authentication for each one.

In what order are Zuul filters executed?

There are four types of standard filters in Zuul: pre for pre-routing filtering, route for routing to an origin, post for post-routing filters, and error for error handling.

How Zuul API gateway works internally?

It handles all the requests and performs the dynamic routing of microservice applications. It works as a front door for all the requests. It is also known as Edge Server. Zuul is built to enable dynamic routing, monitoring, resiliency, and security.

How do you add a prefix to Zuul?

To add a prefix to all mappings, set zuul. prefix to a value, such as /api . By default, the proxy prefix is stripped from the request before the request is forwarded by (you can switch this behavior off with zuul. stripPrefix=false ).


1 Answers

I would do the following:

  1. Drop the zuul.prefix property.
  2. Prepend the prefix of 'apito all of yourzuul.routes.*.path` properties.
  3. Add a final route (to the end of the list) that has the following properties:

app:
  path: /**
  stripPrefix: false

(3) is very important as the order of the routes here matters. This is the order that incoming requests will evaluate whether or not a route matches. It is also important that you do this in yaml, as order will be preserved, where it might not be with a properties file (according to the documentation).

like image 62
nicholas.hauschild Avatar answered Oct 09 '22 17:10

nicholas.hauschild