Spring webflux: как настроить Controller и WebClient для работы как прокси? - PullRequest
0 голосов
/ 30 мая 2018

Мне нужна конечная точка, которая будет работать в режиме прокси: перенаправлять запросы на внешний REST API.В настоящее время я реализовал такой класс, но он очень далек от идеального.

import java.net.URI;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

@RestController
public class ProxyController2 {

  private static final int OFFSET = 4;
  private static final String SCHEME = "http";
  private static final String HOTS = "127.0.0.1";
  private static final String PORT = "9090";

  @RequestMapping("/proxy/public/**")
  public Mono<String> publicProxy(ServerHttpRequest request) {
    HttpMethod httpMethod = request.getMethod();

    if (bodyRequired(httpMethod)) {
      return WebClient.create()
          .method(httpMethod)
          .uri(composeTargetUri(request))
          .headers(headers -> headers.addAll(request.getHeaders()))
          .body(BodyInserters.fromDataBuffers(request.getBody()))
          .retrieve()
          .bodyToMono(String.class);
    } else {
      return WebClient.create()
          .method(httpMethod)
          .uri(composeTargetUri(request))
          .headers(headers -> headers.addAll(request.getHeaders()))
          .retrieve()
          .bodyToMono(String.class);
    }
  }

  private URI composeTargetUri(ServerHttpRequest request) {
    return UriComponentsBuilder.newInstance()
        .scheme(SCHEME)
        .host(HOTS)
        .port(PORT)
        .path(getTargetPath(request))
        .build()
        .toUri();
  }

  private String getTargetPath(ServerHttpRequest request) {
    return request.getPath().pathWithinApplication()
        .subPath(OFFSET)
        .value();
  }

  private boolean bodyRequired(HttpMethod httpMethod) {
    return httpMethod == HttpMethod.DELETE || httpMethod == HttpMethod.POST
        || httpMethod == HttpMethod.PUT;
  }
}

Имеет несколько недостатков:
* Всегда возвращает результаты в виде строки.
* Мы теряем заголовки ответа.
* Мы теряем статус ответа (Выдает 500 с сообщением об ошибкеописание).

Знаете ли вы хороший способ создания прокси-контроллера в весеннем приложении webflux?

1 Ответ

0 голосов
/ 30 мая 2018

Spring Cloud Gateway

API-шлюз, построенный на основе Spring Ecosystem, в том числе: Spring 5, Spring Boot 2 и Project Reactor.Задача Spring Cloud Gateway - предоставить простой, но эффективный способ маршрутизации к API-интерфейсам и обеспечить их сквозные проблемы, такие как: безопасность, мониторинг / показатели и отказоустойчивость.

Doc: SpringОблачный шлюз

...