Affects: \
The new HTTP interface clients only supports WebClient, for MVC users this means an additional dependency on web-flux and dealing with Spring boot auto configuration for web-flux.
Comment From: rstoyanchev
hi @ooraini, thanks for bringing this up.
HttpClientAdapter
can be implemented quite easily with the RestTemplate
. For example:
RestTemplateAdapter
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.service.invoker.HttpClientAdapter;
import org.springframework.web.service.invoker.HttpRequestValues;
public class RestTemplateAdapter implements HttpClientAdapter {
private final RestTemplate restTemplate;
public RestTemplateAdapter(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public Mono<Void> requestToVoid(HttpRequestValues values) {
this.restTemplate.exchange(newRequest(values), Void.class);
return Mono.empty();
}
@Override
public Mono<HttpHeaders> requestToHeaders(HttpRequestValues values) {
HttpHeaders headers = this.restTemplate.exchange(newRequest(values), Void.class).getHeaders();
return Mono.just(headers);
}
@Override
public <T> Mono<T> requestToBody(HttpRequestValues values, ParameterizedTypeReference<T> type) {
T body = this.restTemplate.exchange(newRequest(values), type).getBody();
return Mono.justOrEmpty(body);
}
@Override
public <T> Flux<T> requestToBodyFlux(HttpRequestValues values, ParameterizedTypeReference<T> type) {
throw new UnsupportedOperationException("Not supported with RestTemplate");
}
@Override
public Mono<ResponseEntity<Void>> requestToBodilessEntity(HttpRequestValues values) {
ResponseEntity<Void> entity = this.restTemplate.exchange(newRequest(values), Void.class);
return Mono.just(entity);
}
@Override
public <T> Mono<ResponseEntity<T>> requestToEntity(HttpRequestValues values, ParameterizedTypeReference<T> type) {
ResponseEntity<T> entity = this.restTemplate.exchange(newRequest(values), type);
return Mono.just(entity);
}
@Override
public <T> Mono<ResponseEntity<Flux<T>>> requestToEntityFlux(HttpRequestValues values, ParameterizedTypeReference<T> type) {
throw new UnsupportedOperationException("Not supported with RestTemplate");
}
@SuppressWarnings("ReactiveStreamsUnusedPublisher")
private RequestEntity<?> newRequest(HttpRequestValues values) {
HttpMethod httpMethod = values.getHttpMethod();
Assert.notNull(httpMethod, "HttpMethod is required");
RequestEntity.BodyBuilder builder;
if (values.getUri() != null) {
builder = RequestEntity.method(httpMethod, values.getUri());
}
else if (values.getUriTemplate() != null) {
builder = RequestEntity.method(httpMethod, values.getUriTemplate(), values.getUriVariables());
}
else {
throw new IllegalStateException("Neither full URL nor URI template");
}
builder.headers(headers -> headers.putAll(values.getHeaders()));
// TODO: cookies
if (values.getBodyValue() != null) {
builder.body(values.getBodyValue());
}
else if (values.getBody() != null) {
throw new IllegalArgumentException("Publisher body is not supported");
}
return builder.build();
}
}
Mainly, it's the Flux
methods that are excluded as those cannot be supported with the RestTemplate
, and likewise, it's not an option to use Flux
or Mono
as inputs in @HttpExchange
methods either. Aside from that, the rest should work.
There are a couple of things we can consider as part of this request:
- Providing an implementation like the one above.
- Supporting an alternative
HttpClientAdapter
contract that does not depend on Reactor.
The work for #29552 should also help to inform decisions we make here. In particular of interest is whether a Loom-friendly contract would support asynchronous requests, and streaming with decoding to objects.
Comment From: OlgaMaciaszek
We are going to experiment with this for 6.1
.