- Published on
Spring RestTemplate으로 외부 API 사용 방법
- Authors
- Name
- Chan Sol OH
목차
개요
스프링에서 외부 서버와 API 통신하는 방법은 여러 가지가 있다고 한다.
- Spring RestTemplate
- Java Servlet API를 사용하기 때문에 요청 마다 쓰레드를 할당한다.
- Blocking 처리이므로 응답을 기다릴 때 쓰레드가 대기 상태로 있다.
- 많은 요청이 몰리면 많은 쓰레드가 쌓일 것이고 메모리 사용량이 초과될 수 있다.
- WebClient
- Spring Reactive framework를 사용하여 비동기 방식으로 처리
- RestTemplate이 각 이벤트에 쓰레드를 생성한 것과 달리 Reactive framework는
task
라는 것을 생성한다. - 이벤트 드라이븐 아키텍처를 사용
WebClient은 RestTemplate에 비해 쓰레드를 적게 사용하는 장점이 있다. 하지만 Spring WebFlux 라이브러리의 한 부분이고, 비동기처리를 지원하기 때문에 아직 모르는 부분이 있다. 그래서 이번 실습에서는 비교적 동작 원리가 명확한 RestTemplate을 사용해서 외부 API 호출을 구현해보려고 한다.
RestTemplate의 유용한 메서드들
- getForEntity()
- GET 요청을 수행하고 status code와 응답 객체가 포함된 ResponseEntity class의 객체를 리턴한다.
- getForObject()
- getForEntity와 비슷하지만 응답 객체만 리턴한다.
- headForHeaders()
- HEAR 요청을 보내서 모든 HTTP 헤더 값을 리턴한다.
- delete()
- delete http 메서드를 요청한다.
- put()
- put http 메서드를 요청한다.
- postForObject()
- HTTP POST 메서드를 요청하고, 생성한 entity를 리런탛낟.
요청, 응답에 쓰일 DTO 객체 만들기
공식 DOCS에 적힌 것으로는 아래와 같은 형태로 응답한다고 한다. 이를 Controller에서 응답 받을 수 있도록 DTO를 작성한다.
catImageDTO.json
[{
"id":"41n",
"url":"https://cdn2.thecatapi.com/images/41n.jpg",
"width":2048,"height":1530
}]
catImageDTO.java
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class CatImage {
private String id;
private String url;
private Long width;
private Long height;
}
위와 같은 DTO를 List로 받아서 응답 받을 것이다.
RestTemplate을 이용한 Service 만들기
getCatImages.java
@Service
@RequiredArgsConstructor // 생성작를 통한 DI
public class CatPhotosService implements CatPhoto {
// 생성작를 통한 DI
private final RestTemplate restTemplate;
@Value("${api.cat.host.url}")
public String hostUrl=null;
@Value("${api.cat.xkey}")
public String xkey=null;
@Override
public List<CatImage> getCatImages(Long imageNumber) {
URI uri = UriComponentsBuilder
.fromUriString(hostUrl)
.path("/images/search")
.queryParam("limit",imageNumber)
.encode()
.build()
.toUri();
HttpHeaders headers = new HttpHeaders();
headers.set("x-api-key",xkey);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<List<CatImage>> responseEntity = restTemplate.exchange(uri,
HttpMethod.GET, entity, new ParameterizedTypeReference<List<CatImage>>() {
});
System.out.println(responseEntity);
return responseEntity.getBody();
}
}
http entity를 이용해서 헤더를 설정하고 application.properties
에서 xkey를 받아서 인증 정보를 보냈다. 또한 RestTemplate의 GET요청을 통해 이미지 데이터를 받았다.
Controller로 API 만들기
controller.java
@RestController
@RequiredArgsConstructor
public class imageController {
private final CatPhotosService catPhotosService;
@RequestMapping(value = "/api/v1/images", method = RequestMethod.GET)
public List<CatImage> getImages(@RequestParam Long imageNumber){
return catPhotosService.getCatImages(imageNumber);
}
}
앞으로...
다만, 앞으로 비동기처리 방식인 WebFlux를 자주 사용할 것이라는 얘기가 많이 나오고 있다. 비동기 처리의 위험성 (데드락, 레이스 컨디션) 같은 것을 잘만 처리하면 적은 쓰레드를 써서 더 많은 요청을 처리할 수 있고, CPU, 메모리 사용량이 더 적기 때문인 것 같다.
다음에는 WebClient를 이용한 API 요청이나 WebFlux를 이용한 비동기처리도 포스팅하겠다.