I have some microservices discovered with Eureka. Most of them provide some APIs. And I have an "edge" service called the "Gateway service", which is actually a Zuul Proxy. The fact is that there is a web application. It was supported by a gateway for a long time, and there were no problems with it. But now I need to place this client on a separate service behind the gateway. It's not a problem. I created a new service and hosted a web application there. But the fact is that Zuul on the gateway has the following 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 make it so that the user can access the web application from the root path, like this http://app.com/ . But right now, I can only access it using http://app.com/api/ , which is completely wrong.
My task:
- Make the web application hosted on another service accessible from the root path.
- It is also very important that the
/api prefix remains for all other services.
I tried to implement ZuulFilter . But it seems that it does nothing with the root path and only works when there is a match with any routes described above.
How can I do this job?
UPDATE . I have little success with ZuulFilter . I made it work. Here is the Zuul configuration:
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 himself
@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 a property zuul.routes.api=/api/** , which does nothing. It just allows you to map all matched paths to the Zuul filter chain ( described in the documentation ). All other routes described here are set as if there is no /api . It allows you to achieve such services: http://app.com/requests for example. to service requests. ZuulFilter performs a check for each request described in the properties, but only works if the requested URI starts with /api and it redirects that request in the same way as if there was no /api in the path.
It really works. But I still don't like this solution, because endpoints without the /api prefix still remain on the gateway. Maybe someone knows how to improve it?
java spring-boot spring-cloud netflix-zuul
Valeriy Maslov
source share