Files
spring-boot-examples/docs/resttemplate.md
2025-04-08 19:56:24 +09:00

6.9 KiB

스프링 부트의 RestTemplate에 대한 설명

스프링 부트에서 RestTemplate은 외부 HTTP 서비스와 통신하기 위한 동기식(Synchronous) REST 클라이언트입니다. 스프링 프레임워크에서 제공하는 이 클래스는 HTTP 요청(GET, POST, PUT, DELETE 등)을 쉽게 보내고 응답을 처리할 수 있도록 설계되었습니다. RESTful API 호출이 필요한 경우, RestTemplate은 간단한 설정과 직관적인 API로 개발자가 빠르게 통합할 수 있게 해줍니다. 아래에서 설정, 사용 방법, 주요 기능을 설명합니다.


1. RestTemplate의 기본 개념

  • 동기식: 요청을 보내고 응답을 기다린 후 결과를 반환합니다 (비동기 처리는 WebClient 추천).
  • HTTP 메서드 지원: GET, POST, PUT, DELETE 등 모든 표준 HTTP 메서드 지원.
  • 유연성: 요청 헤더, 바디, 응답 타입 등을 커스터마이징 가능.
  • 스프링 통합: 스프링의 의존성 주입과 설정을 활용해 쉽게 사용.

2. 의존성

RestTemplatespring-boot-starter-web에 포함되어 별도 의존성 추가 없이 사용 가능합니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. 기본 설정

RestTemplate은 스프링 빈으로 등록해 사용할 수 있습니다. 기본 설정은 스프링 부트가 자동으로 제공하지만, 필요 시 커스터마이징 가능합니다.

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
            .setConnectTimeout(Duration.ofSeconds(5))  // 연결 타임아웃 5초
            .setReadTimeout(Duration.ofSeconds(10))    // 읽기 타임아웃 10초
            .build();
    }
}
  • RestTemplateBuilder: 타임아웃, 인터셉터, 메시지 컨버터 등을 설정.

4. RestTemplate 사용 예시

(1) GET 요청
@Service
public class UserService {

    private final RestTemplate restTemplate;

    public UserService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public User getUser(Long id) {
        String url = "https://api.example.com/users/{id}";
        return restTemplate.getForObject(url, User.class, id);
    }

    public ResponseEntity<User> getUserWithResponse(Long id) {
        String url = "https://api.example.com/users/{id}";
        return restTemplate.getForEntity(url, User.class, id);
    }
}

@Data
public class User {
    private Long id;
    private String name;
    private int age;
}
  • getForObject: 응답 본문을 직접 객체로 변환.
  • getForEntity: HTTP 상태 코드, 헤더, 본문을 포함한 ResponseEntity 반환.
(2) POST 요청
public User createUser(User user) {
    String url = "https://api.example.com/users";
    return restTemplate.postForObject(url, user, User.class);
}
  • postForObject: 요청 바디에 객체를 보내고 응답 객체 반환.
  • 참고: JSON 직렬화는 Jackson 라이브러리에 의존 (기본 포함).
(3) PUT 요청
public void updateUser(Long id, User user) {
    String url = "https://api.example.com/users/{id}";
    restTemplate.put(url, user, id);
}
  • put: 응답 본문이 필요 없는 업데이트 작업.
(4) DELETE 요청
public void deleteUser(Long id) {
    String url = "https://api.example.com/users/{id}";
    restTemplate.delete(url, id);
}
  • delete: 리소스 삭제 요청.
(5) 커스텀 요청 (exchange)
public User customRequest(Long id) {
    String url = "https://api.example.com/users/{id}";
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "Bearer token123");
    HttpEntity<String> entity = new HttpEntity<>(headers);

    ResponseEntity<User> response = restTemplate.exchange(
        url, HttpMethod.GET, entity, User.class, id
    );
    return response.getBody();
}
  • exchange: HTTP 메서드, 헤더, 바디를 자유롭게 설정 가능.

5. 주요 메서드

  • getForObject(String url, Class<T> responseType, Object... uriVariables): GET 요청 후 객체 반환.
  • getForEntity(String url, Class<T> responseType, Object... uriVariables): GET 요청 후 ResponseEntity 반환.
  • postForObject(String url, Object request, Class<T> responseType): POST 요청 후 객체 반환.
  • put(String url, Object request, Object... uriVariables): PUT 요청 실행.
  • delete(String url, Object... uriVariables): DELETE 요청 실행.
  • exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables): 모든 HTTP 메서드에 대한 유연한 요청.

6. 에러 처리

RestTemplate은 HTTP 오류(4xx, 5xx)를 RestClientException으로抛출합니다. 이를 처리하려면 try-catch 사용:

try {
    User user = restTemplate.getForObject("https://api.example.com/users/999", User.class);
    return user;
} catch (HttpClientErrorException e) {
    // 4xx 오류 처리 (예: 404 Not Found)
    log.error("Client error: {}", e.getStatusCode());
    return null;
} catch (HttpServerErrorException e) {
    // 5xx 오류 처리 (예: 500 Internal Server Error)
    log.error("Server error: {}", e.getStatusCode());
    return null;
}
  • 커스텀 에러 핸들러:
    restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            // 커스텀 처리
        }
    });
    

7. 장점과 한계

  • 장점:
    • 사용이 간단하고 직관적.
    • 스프링 생태계와 잘 통합.
    • 다양한 HTTP 요청 지원.
  • 한계:
    • 동기식이라 비동기 작업에는 부적합 (WebClient 권장).
    • 대규모 병렬 요청 처리 시 성능 저하 가능.
    • 스프링 5.0 이후 WebClient로 대체되는 추세 (유지보수 모드).

8. WebClient와의 비교

  • RestTemplate: 동기식, 간단한 REST 호출에 적합.
  • WebClient: 비동기/리액티브, 대규모 트래픽 및 스트리밍에 적합.
  • 권장: 새로운 프로젝트라면 WebClient 고려, 기존 코드 유지보수 시 RestTemplate 사용.

9. 결론

RestTemplate은 스프링 부트에서 외부 REST API 호출을 쉽게 처리할 수 있는 도구로, 동기식 요청이 필요한 환경에서 유용합니다. 기본 메서드로 간단한 GET/POST 요청을 처리하거나, exchange로 복잡한 요청을 커스터마이징할 수 있습니다. 비록 WebClient가 최신 트렌드로 자리잡았지만, RestTemplate은 여전히 간단한 시나리오에서 강력한 선택지입니다. 위 예시를 참고하면 RESTful 통신을 빠르게 구현할 수 있습니다. 추가 질문이 있다면 언제든 물어보세요!