One of the request that comes to my Zuul Filter is of URI /hello/World which i want to redirect to /myapp/test. This /myapp/test is a service that is registered in Eureka.
zuul:
routes:
xyz:
path: /hello/World
url: http://localhost:1234/myapp/test
stripPrefix: true
When i try the above configuration, the incoming URI is suffixed to the configured URL like http://localhost:1234/myapp/test/World . Few of the links which i came across seem to be stating that URL Rewrite feature is not yet available in Zuul.
Is there any other way this can be done at the Zuul Layer ?
Note: At this point of time, i cannot do this reverse proxying in the Webserver or any other layer since, my Zuul filter is the one that is receiving the request directly.
Using @Adelin solution, with little improvements
Use 'url' property as path to prepend for customizing the Url rewriting (I have disabled Eureka in my example) :
ribbon.eureka.enabled=false
zuul.routes.route1.path=/route1/**
zuul.routes.route1.serviceId=service1
zuul.routes.route1.url=/path/to/prepend
service1.ribbon.listOfServers=http://server1
Then implement the following filter :
/**
* Fixing missing URL rewriting when using ribbon
*/
@Component
public class CustomPathZuulFilter extends ZuulFilter {
@Autowired
private ZuulProperties zuulProperties;
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter() {
// override PreDecorationFilter only if executed previously successfully
return RequestContext.getCurrentContext().getFilterExecutionSummary().toString()
.contains("PreDecorationFilter[SUCCESS]");
}
@Override
public Object run() {
final RequestContext context = RequestContext.getCurrentContext();
if (context.get(FilterConstants.SERVICE_ID_KEY) == null || context.getRouteHost() != null) {
// not a Ribbon route
return null;
}
// get current ZuulRoute
final String proxy = (String) context.get(FilterConstants.PROXY_KEY);
final ZuulRoute zuulRoute = this.zuulProperties.getRoutes().get(proxy);
// patch URL by prefixing it with zuulRoute.url
final Object originalRequestPath = context.get(FilterConstants.REQUEST_URI_KEY);
final String modifiedRequestPath = zuulRoute.getUrl() + originalRequestPath;
context.put(FilterConstants.REQUEST_URI_KEY, modifiedRequestPath);
// patch serviceId because :
// - has been set to route.location in PreDecorationFilter
// - route.location has been set to zuulRoute.location in SimpleRouteLocator
// - zuulRoute.location return zuulRoute.url if set
context.set(FilterConstants.SERVICE_ID_KEY, zuulRoute.getServiceId());
return null;
}
}
Now calls to /route1 will be proxified to http://server1/path/to/prepend
This solution is also compatible with co-existing routes not using Ribbon.
Example of a co-existing route not using Ribbon :
zuul.routes.route2.path=/route2/**
zuul.routes.route2.url=http://server2/some/path
Calls to /route2 will be proxified to http://server2/some/path by SimpleHostRoutingFilter (if not disabled)
Here is a posted solution in the link by @Vikash
@Component
public class CustomPathZuulFilter extends ZuulFilter
{
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return PreDecorationFilter.FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
Object originalRequestPath = context.get(REQUEST_URI_KEY);
String modifiedRequestPath = "/api/microservicePath" + originalRequestPath;
context.put(REQUEST_URI_KEY, modifiedRequestPath);
return null;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With