REST API 구현은 Spring Boot 개발에서 중요한 요소입니다. 이 글에서는 Spring Boot에서 RestTemplate을 사용하여 시스템 부하 시에도 안정성을 유지할 수 있는 API 구현 방법을 4단계로 설명합니다. 타임아웃 및 재시도 로직 설정을 통해 안정성을 높이는 방법을 알아보세요.
코드 예제: Spring Boot에서 RestTemplate
을 사용한 요청/응답 구현
아래는 Spring Boot 환경에서 시스템 부하가 발생할 때 안정적인 요청/응답을 처리하는 RestTemplate
설정, Dto, 서비스 계층 코드 예시입니다.
1. RestTemplate 설정
RestTemplate 설정은 API 요청의 타임아웃을 관리하고 시스템 부하를 제어하는 중요한 요소입니다.
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setConnectTimeout(5000); // 커넥션 타임아웃 5초 factory.setReadTimeout(5000); // 리드 타임아웃 5초 return new RestTemplate(factory); } }
2. DTO 설계
DTO (Data Transfer Object)를 설계하여 데이터를 구조화합니다. REST API의 요청과 응답에 필요한 정보를 정의합니다.
// 요청 DTO public class ReqDto { private String name; // 생성자, getter, setter 추가 public ReqDto() {} public ReqDto(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } // 응답 DTO public class ResDto { private String message; private String status; // 생성자, getter, setter 추가 public ResDto() {} public ResDto(String message, String status) { this.message = message; this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } }
3. 서비스 계층에 타임아웃 및 재시도 로직 적용하기
서비스 계층에서 타임아웃과 재시도 로직을 통해 안정성을 강화합니다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import java.util.concurrent.TimeUnit; @Service public class ApiService { private final RestTemplate restTemplate; private final String externalApiUrl = "https://example.com/api"; // 실제 URL로 변경 필요 @Autowired public ApiService(RestTemplate restTemplate) { this.restTemplate = restTemplate; } public ResDto fetchData(ReqDto reqDto) { int maxRetries = 3; // 최대 재시도 횟수 int retries = 0; while (retries < maxRetries) { try { // 요청 생성 HttpEntity<ReqDto> requestEntity = new HttpEntity<>(reqDto); // 외부 API 호출 ResponseEntity<ResDto> response = restTemplate.exchange( externalApiUrl, HttpMethod.POST, requestEntity, ResDto.class ); // 응답이 성공적으로 도착했을 경우 리턴 return response.getBody(); } catch (RestClientException e) { retries++; try { // 재시도 전 대기 TimeUnit.SECONDS.sleep(1); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("Thread interrupted during retry delay", ie); } if (retries >= maxRetries) { // 최대 재시도 횟수를 초과했을 경우 기본 응답 반환 return new ResDto("Service unavailable", "ERROR"); } } } return new ResDto("Unknown error", "ERROR"); } }
4. 컨트롤러 계층으로 API 엔드포인트 구현하기
컨트롤러에서 엔드포인트를 정의하고, 클라이언트 요청을 처리합니다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api") public class ApiController { private final ApiService apiService; @Autowired public ApiController(ApiService apiService) { this.apiService = apiService; } @PostMapping("/fetch-data") public ResponseEntity<ResDto> fetchData(@RequestBody ReqDto reqDto) { ResDto response = apiService.fetchData(reqDto); if ("ERROR".equals(response.getStatus())) { return new ResponseEntity<>(response, HttpStatus.SERVICE_UNAVAILABLE); } return new ResponseEntity<>(response, HttpStatus.OK); } }
결론
Spring Boot에서 RestTemplate을 활용하여 REST API의 안정성을 높이는 방법은 시스템 부하 시에도 중요한 요소입니다. 타임아웃 설정과 재시도 로직을 통해 견고한 API 구현이 가능하며, 이를 통해 애플리케이션의 안정성을 강화할 수 있습니다.