'spring cloud gateway - Create dynamic java routes
I created my bean like this:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder, LoggingGatewayFilterFactory loggingFactory) {
return builder.routes()
.route("configuracionApp",
r -> r.path("/configuracion")
.and().readBody(String.class, requestBody -> true)
.filters(
f -> f
.filter(loggingFactory.apply(new Config("My Custom Message", true, true)))
.modifyResponseBody(String.class, String.class, bodyRewrite)
)
.uri("lb://msapp")
)
.route("configuracionHorario",
r -> r.path("/configuracion/horario")
.filters(
f -> f
.filter(loggingFactory.apply(new Config("My Custom Message", true, true)))
.modifyResponseBody(String.class, String.class, bodyRewrite)
)
.uri("lb://msapp")
)
.build();
}
Everything works perfect, my only doubt is if I can create those routes from a list, and have that list in a yml file for example,
Thanks in advance
Solution 1:[1]
I define a list of routes in :
application.yml
application:
routes:
-
id: referential
path: /referential/**
uri: https://referential.p.rapidapi.com
-
id: muslimsalat
path: /muslimsalat/**
uri: https://muslimsalat.p.rapidapi.com
I define a configuration properties class to map properties in
RouteConfigProperties.java
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Configuration
@ConfigurationProperties(prefix = "application")
@Data
public class RouteConfigProperties
{
private List<CustomRoute> routes;
@Data
public static class CustomRoute
{
private String id;
private String path;
private String uri;
}
}
Finally i define my GatewayRouteConfig class in
RouteConfig.java
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder.Builder;
@Configuration
public class RouteConfig {
private final RouteConfigProperties routeConfigProperties;
public RouteConfig(RouteConfigProperties routeConfigProperties) {
this.routeConfigProperties = routeConfigProperties;
}
@Bean
RouteLocator staticRoutes(RouteLocatorBuilder builder)
{
Builder build = builder.routes();
routeConfigProperties.getRoutes().forEach(customRoute -> {
build.route(
customRoute.getId(),
route -> route.path(customRoute.getPath())
.filters(filter -> filter.addRequestHeader("x-rapidapi-host", String.format("%s.p.rapidapi.com", customRoute.getId()))
.addRequestHeader("x-rapidapi-key", "2bb4b6cd95msh13bd91f0c332909p10dc79jsn9e98442d4457")
.rewritePath(String.format("/%s/(?<segment>.*)", customRoute.getId()), "/${segment}"))
.uri(customRoute.getUri()));
});
return build.build();
}
}
Don't forget to enabled configuration properties in :
GatewayServiceApplication.java
import org.sid.gatewayservice.config.RouteConfigProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties({ RouteConfigProperties.class })
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
Solution 2:[2]
If you want routes in a file, why not use the Path Route predicate provided by spring cloud gateway - https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-path-route-predicate-factory
There is are a ton of filters there too that can change requests and responses.
To change requests and responses of routes that are not provided the filters provided by spring, you can create your own custom filters - GlobalFilter
or GatewayFilters
. For reference on how to implement, you can see their repo (for eg. how did they implement AddRequestHeader filter).
While global filters apply to all routes. GatewayFilters can be mapped to a specific one. For example, if you created a custom Filter called MyCustomFilter
and you want it to be applied only in /foo/*
requests, you can do somehting like:
spring:
cloud:
gateway:
routes:
- id:
uri: https://example.org # or lb://my-service
predicates:
- Path=/foo/**
filters:
- MyCustomFilter
To check which filters got applied to which routes you can see in the actuator gateway routes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |