Kamil W
Kamil W

Reputation: 2376

RestController - Forward POST request to external URL

I'm looking for a way how to forward POST request which has been made to endpoint in @RestController class and forward it to external URL with body and headers untouched (and return response from this API of course), is it possible to do it by using some spring features? The only solution which I have found is extracting a body from @RequestBody and headers from HttpServletRequest and use RestTemplate to perform a request. Is there any easier way?

@RequestMapping("/**")
public ResponseEntity mirrorRest(@RequestBody(required = false) String body, 
    HttpMethod method, HttpServletRequest request, HttpServletResponse response) 
    throws URISyntaxException {
    String requestUrl = request.getRequestURI();

    URI uri = new URI("http", null, server, port, null, null, null);
    uri = UriComponentsBuilder.fromUri(uri)
                              .path(requestUrl)
                              .query(request.getQueryString())
                              .build(true).toUri();

    HttpHeaders headers = new HttpHeaders();
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String headerName = headerNames.nextElement();
        headers.set(headerName, request.getHeader(headerName));
    }

    HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
    RestTemplate restTemplate = new RestTemplate();
    try {
        return restTemplate.exchange(uri, method, httpEntity, String.class);
    } catch(HttpStatusCodeException e) {
        return ResponseEntity.status(e.getRawStatusCode())
                             .headers(e.getResponseHeaders())
                             .body(e.getResponseBodyAsString());
    }
}

The above code is taken from this answer.

Upvotes: 4

Views: 3295

Answers (1)

James Martin
James Martin

Reputation: 1060

This is more a matter of the HTTP spec than Spring where the server would be expected to return a 307 redirect status, indicating the client should follow the redirect using the same method and post data.

This is generally avoided in the wild as there's a lot of potential for misuse, and friction if you align with the W3.org spec that states the client should be prompted before re-executing the request at the new location.

One alternative is to have your Spring endpoint act as a proxy instead, making the POST call to the target location instead of issuing any form of redirect.

307 Temporary Redirect (since HTTP/1.1) In this occasion, the request should be repeated with another URI, but future requests can still use the original URI.2 In contrast to 303, the request method should not be changed when reissuing the original request. For instance, a POST request must be repeated using another POST request.

Upvotes: 1

Related Questions