Я новичок в Spring-Cloud-Gateway и не могу ответить на вопрос, если я решил свою проблему намеченным способом.Я надеюсь, что кто-то может указать мне правильное направление, дать совет или предоставить примерный пример кода.
Требование: входящий запрос в моем сервисе spring-cloud-gateway должен быть перенаправлен в правильный бэкэнд-сервис (естьХ таких бэкэнд-сервисов, каждый из которых отвечает за определенную задачу).Сам запрос не содержит достаточной информации, чтобы решить, к какой серверной службе следует направить.
Существует дополнительная REST-служба, которая отображает произвольный URL-адрес-для-ответной-службы-имени.Формат ответа - это небольшой файл JSON, содержащий имя бэкэнд-службы для переадресации.
Каким было бы самое простое / лучшее / самое умное / предназначенное решение для реализации этой функциональности с помощью spring-cloud-gateway?
Я попытался реализовать GatewayFilter
, который сначала вызывает службу сопоставления и в зависимости от набора результатов GATEWAY_REQUEST_URL_ATTR
для обмена.Это работает хорошо.Но у меня есть дополнительные вопросы.
Можно ли пропустить часть .uri("not://needed"))
в настройке маршрута?
Почему стоимость заказа должна быть выше 9999?(см. пример кода)
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes().route(r -> r
.alwaysTrue()
.filters(f -> f.filter(new CustomRequestFilter()))
.uri("not://needed")) // how to omit ?
.build();
}
public static class CustomRequestFilter implements GatewayFilter, Ordered {
@Override
public int getOrder() {
return 10000; // why order > 9999 ? (below 10000 does not work)
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return getBackendServiceMappingResult(exchange.getRequest().getURI().toString()) //async call to REST service mapping URL->backend service name
.flatMap(mappingResult -> {
URI uri = mapServiceNameToBackendService(mappingResult.getServiceName());
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, uri);
return chain.filter(exchange);
});
}
private URI mapServiceNameToBackendService(String serviceName) {
try {
switch (serviceName) {
case "serviceA": return new URI("http://httpbin.org:80/get");
case "serviceB": return new URI("https://someotherhost:443/");
}
} catch (URISyntaxException e) {
//ignore
}
return null;
}
}
static class MappingResult {
String serviceName;
public String getServiceName() {
return serviceName;
}
}
static Mono<MappingResult> getBackendServiceMappingResult(String uri) {
WebClient client = WebClient.create("http://localhost:8080");
return client.get().uri(uriBuilder -> uriBuilder.path("/mapping").queryParam("uri", uri).build()).retrieve().bodyToMono(MappingResult.class);
}
}
Существует ли лучший подход (с весенним облаком-шлюзом) для решения требования?