본문 바로가기

spring

RestTemplate을 통해서 API 호출하기

RestTemplate 이란?

spring framework 에서 제공하는 고수준 HTTP API 라이브러리이다.

RestTemplate을 사용하여 GET 요청하기

RestTemplate template = new RestTemplate();

ResponseEntity<String> response = template.getForEntity("http://test.com", String.class);

String body = response.getBody();

RestTemplate을 사용하여 POST 요청하기

  • exchange 사용하기
 RestTemplate template = new RestTemplate();

RequestEntity requestEntity = RequestEntity.post("https://test.com")
.header("Authorization", "token")
.accept(MediaType.APPLICATION_FORM_URLENCODED)
.acceptCharset(StandardCharsets.UTF_8)
.body("{ \"data\":\"hello\"}");

ResponseEntity<String> response = template.exchange(requestEntity, String.class);
String body = response.getBody();
  • postForEntity 사용하기
RestTemplate template = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

MultiValueMap<String, String> bodyParams = new LinkedMultiValueMap<>();
bodyParams.add("redirect_uri", "http://google.com");
bodyParams.add("auth", "hello");

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(bodyParams, headers);

ResponseEntity<String> response = template.postForEntity("http://test.com", request, String.class);
String body = response.getBody();
  • Multipart body 만들기
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();

parts.add("fieldPart", "fieldValue");
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("jsonPart", new Person("Jason"));

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
parts.add("xmlPart", new HttpEntity<>(myBean, headers));

RestTemplate이 제공하는 메서드

메서드 이름 설명
getForObject get 요청 후 body 데이터를 객체 형태로 반환
getForEntity get 요청 후 http 메시지를 ResponseEntity 객체 형태로 반환
headForHeaders head 요청 후 헤더 정보를 반환
postForLocation post 요청 후 생성된 리소스의 위치 정보를 반환
postForObject post 요청 후 응답 메시지의 body 데이터를 객체 형태로 반환
postForEntity post 요청 후 응답 메시지를 ResponseEntity 객체 형태로 반환
put put 요청 후 반환 값 없음
patchForObject patch 요청 후 body 데이터를 객체 형태로 반환
delete delete 요청 후 반환 값 없음
optionsForAllow options 요청 후 가능한 메서드 목록 반환
exchange 커스텀한 http 요청을 생성할 때 사용하는 메서드
execute 커스텀한 http 요청을 생성할 때 사용하는 메서드로써 callback 함수를 지정할 수 있다.

RestTemplate 초기화하는 법

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
RestTemplate template = new RestTemplate(factory);

uriTemplate?

uri의 동적인 파라미터 값을 정적인 템플릿에 맞추어서 랜더링하기 위한 규칙이다.

String uriTemplate = "https://example.com/hotels/{hotel}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42);

가변적인 값은 {} 로 감싸서 템플릿을 만들고 build() 메서드를 통해서 값을 입력할 수 있다.


WebClient?

비동기 REST API 요청 클라이언트 라이브러리로서 동기, 비동기, 스트리밍을 지원한다.
Spring Webflux와 같은 비동기 어플리케이션을 개발하려면 WebClient를 사용해야한다.


주의할 점

RestTemplate은 기본적으로 커넥션 풀을 사용하지 않는다. 그래서 많은 요청을 하면 TIME_WAIT으로 인해 자원이 부족해져 서비스에 장애를 가져올 가능성이 있다. 이를 해결하기 위해서 커넥션 풀을 만들어 사용하기를 권장하고 있다.

# 코드 소스 참고 : https://nesoy.github.io/articles/2020-05/RestTemplate
CloseableHttpClient httpClient = HttpClientBuilder.create()
    .setMaxConnTotal(120) // maxConnTotal은 연결을 유지할 최대 숫자
    .setMaxConnPerRoute(60) // maxConnPerRoute는 특정 경로당 최대 숫자
    .setConnectionTimeToLive(5, TimeUnit.SECONDS) // keep - alive
    .build();

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(5000); // 읽기시간초과, ms
factory.setConnectTimeout(3000); // 연결시간초과, ms
factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅

this.restTemplate = new RestTemplate(factory);

Reference

Spring Framework reference
주의할 점
HTTP 서버 클라이언트 라이브러리 장단점