-
Notifications
You must be signed in to change notification settings - Fork 38.5k
HTTP interface client infrastructure and adapter for RestTemplate #30117
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
hi @ooraini, thanks for bringing this up.
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 There are a couple of things we can consider as part of this request:
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. |
We are going to experiment with this for |
Now that HttpClientAdapter is deprecated and replaced by HttpExchangeAdapter and ReactorHttpExchangeAdapter, our tests should use the new contracts. See gh-30117
HTTP interface client argument resolvers for RequestBody and RequestPart now handle reactive input conditionally. See gh-30117
Affects: <Spring Framework version>
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.
The text was updated successfully, but these errors were encountered: