API 요청
자동화 프로그램을 개발 중 "그간 배웠던 HTTP 요청은 url 매핑을 통해서 구현했는데, 웹이 아닐 때는 API 요청을 어떻게 보내지?" 하는 의문이 들어 검색해봤다.
HTTP 요청을 간단하게 보낼 수 있는 스프링 인터페이스들이 있다.
RestTemplate
: 스프링 3.0 에서부터 지원하는 내장 객체로 Block & 동기 방식을 지원한다.
하지만 deprecated 이슈가 있을만큼 더 이상의 지원은 기대하기 어렵다.
Config
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
restTemplate.setDefaultURI(URI.create(requestUrl));
restTemplate.getInterceptors().add((request, body, execution) -> {
request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return execution.execute(request, body);
});
return restTemplate;
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(10000); // 연결 timeout 10초
factory.setReadTimeout(30000); // 응답 timeout 30초
return factory;
}
Service
@Autowired
private RestTemplate restTemplate;
public void sendErrorReport(EmailRequestDto emailRequestDto) {
try {
ResponseEntity<String> response = restTemplate.postForEntity("/", emailRequestDto, String.class);
HttpStatusCode statusCode = response.getStatusCode();
String responseBody = response.getBody();
log.info("API 요청 Status Code: {}", statusCode.value());
log.info("API 요청 Response Body: {}", responseBody);
} catch (RestClientException e) {
log.error("API 요청 중 오류 발생: ", e);
}
}
WebClient
: 스프링 5.0 에서부터 지원하는 인터페이스로 Non-Block & 비동기 방식을 지원한다.
또한 체인메서닝, 람다를 지원하며 보다 모던하게 사용할 수 있다.
하지만 WebFlux 의 의존이 필요하며, Mono와 Flux라는 값을 사용하여 응답값을 받는 작업의 학습 난이도가 높은 것 같다.
Config
@Bean
public WebClient webClient() {
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
.responseTimeout(Duration.ofMillis(30000));
return WebClient.builder()
.baseUrl(requestUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
Service
@Autowired
private WebClient webClient;
public void sendErrorReport(EmailRequestDto emailRequestDto) {
webClient.post()
.bodyValue(emailRequestDto)
.retrieve()
.toEntity(String.class)
.subscribe(response -> {
HttpStatusCode statusCode = response.getStatusCode();
String responseBody = response.getBody();
log.info("API 요청 Status Code: {}", statusCode.value());
log.info("API 요청 Response Body: {}", responseBody);
}, error -> {
log.error("API 요청 중 오류 발생: ", error);
});
log.info("API 요청 전송 완료");
}
RestClient
: 스프링 6.1 에서부터 지원하는 인터페이스로 Block & 동기 방식을 지원한다.
RestTemplate를 WebClient 처럼 모던한 방식으로 풀어내 보다 직관적인 사용법이다.
Config
@Bean
public RestClient restClient() {
return RestClient.builder()
.baseUrl(requestUrl)
.requestFactory(clientHttpRequestFactory())
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(10000); // 연결 timeout 10초
factory.setReadTimeout(30000); // 응답 timeout 10초
return factory;
}
Service
@Autowired
private RestClient restClient;
public void sendErrorReport(EmailRequestDto emailRequestDto) {
ResponseEntity<String> response = restClient.post()
.body(emailRequestDto) // JSON 형식으로 변환해줌
.retrieve()
.toEntity(String.class);
HttpStatusCode statusCode = response.getStatusCode();
String responseBOdy = response.getBody();
log.info("API 요청 Status Code: {}", statusCode.value());
log.info("API 요청 Response Body: {}", responseBOdy);
}
참고로 위의 인터페이스들은 스프링 내부에서 Jackson 라이브러리를 통해 자동으로 Json 형식으로 변환해준다.
개인적으로는 동시성을 고려할만한 프로젝트가 아니라면 RestClient를 쭉 사용할 것 같다.
참고
'Backend > Spring' 카테고리의 다른 글
YAML 설정 값 가져오기 (0) | 2024.11.06 |
---|---|
JDBC 이해 (0) | 2024.08.25 |
파일 업로드 (0) | 2024.08.23 |
[SpringBoot] JPA - PersistentBag (0) | 2024.03.27 |
[Spring Security 6] - 현재 인증된(로그인) 유저 정보 가져오기 (0) | 2024.01.19 |