
Overview:
Hello everyone, In this blog, we will deep down into routing predicate factories. Firstly we will know about what is a routing predicate factory? In a nutshell, a Predicate in Spring Cloud Gateway is an object that tests if the given request fulfills a given condition. For each route, we can define one or more prepositions. If satisfied, we accept requests for configured backend after installing any filters.
We will choose any one of the built-in predicate factories, which are available within the org.springframework.cloud.gateway.handler.predicate package of the spring-cloud-gateway-core module (https://github.com/spring-cloud/spring-cloud-gateway/tree/v2.1.3.RELEASE/spring-cloud-gateway-core). Ready to effortlessly spot the existing ones since their names all concludes in RoutePredicateFactory. HeaderRouterPredicateFactory could be a great example. So let us take an example of a routing predicate factory:
public class HeaderRoutePredicateFactory extends
AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
// omitting setup code
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
// omitting predicate logic
}
};
}
@Validated
public static class Config {
public Config(boolean isGolden, String customerIdCookie ) {
// omitting constructor details
}
// omitting getter/setter
}
}
From the above code, we can see that it is extending the AbstractRoutePredicateFactory. As a result, it implements the RoutePredicateFactory interface used by the gateway. Now let us move forward and implement the custom predicate factory.
Implementation of Custom Predicate Factory:
For implementing a predicate factory, let us take a scenario. In a given API, suppose we have to select between two possible backends. “Service1”, which is most valuable, should be routed to an effective server.
They can access more memory, more CPU, and quick disks. Service2 goes to a less capable server, which comes about in slower reaction times. To determine whether the ask comes from a Service1, we’ll need to call a service that takes the customerId associated with the request and returns its status. As for the customerId, in our simple scenario, we’ll assume it is available in a cookie.
So let us write the custom predicate with the help of these examples.
public class Service1RoutePredicateFactory extends
AbstractRoutePredicateFactory<Service1RoutePredicateFactory.Config> {
private final Service1 service;
// ... omitting the constructorhttps://i.postimg.cc/jjf07k2F/springcloudgateway-171219185148-thumbnail-4.jpg
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return (ServerWebExchange t) -> {
List<HttpCookie> cookies = t.getRequest()
.getCookies()
.get(config.getCustomerIdCookie());
boolean isService;
if ( cookies == null || cookies.isEmpty()) {
isService = false;
} else {
String customerId = cookies.get(0).getValue();
isService = Service1.isService1(customerId);
}
return config.isGolden() ? isGolden : !isGolden;
};
}
@Validated
public static class Config {
boolean isSerivce = true;
@NotEmpty
String customerIdCookie = "customerId";
// omitting mutators and constructors
}
}
In the above code apply method returns a lambda which implements the logic using the ServerWebExchange passed to it. So now let us move towards registering the custom predicate factory.
Registering the Custom Predicate Factory:
After implementing the custom predicate factory, we want the Spring Cloud API gateway aware of it.
As we are using Spring, we declare bean type Service1RoutePredicateFactory. So let us create a bean using the @Configuration annotation.
@Configuration
public class CustomPredicatesConfig {
@Bean
public Service1RoutePredicateFactory service1(
Service1 service1) {
return new ServiceRoutePredicateFactory(Service1);
}
}
Conclusion:
Basically in this blog, we have covered how to implement and register Custom Predicate Factory to Spring Cloud API Gateway. Now you are ready to go to implement Custom Predicate Factory to Sring Cloud API gateway. For more, you can refer to the documentation: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RELEASE/single/spring-cloud-gateway.html