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

193 lines
6.9 KiB
Markdown

### 스프링 부트의 RestTemplate에 대한 설명
스프링 부트에서 `RestTemplate`은 외부 HTTP 서비스와 통신하기 위한 동기식(Synchronous) REST 클라이언트입니다. 스프링 프레임워크에서 제공하는 이 클래스는 HTTP 요청(GET, POST, PUT, DELETE 등)을 쉽게 보내고 응답을 처리할 수 있도록 설계되었습니다. RESTful API 호출이 필요한 경우, `RestTemplate`은 간단한 설정과 직관적인 API로 개발자가 빠르게 통합할 수 있게 해줍니다. 아래에서 설정, 사용 방법, 주요 기능을 설명합니다.
---
#### 1. RestTemplate의 기본 개념
- **동기식**: 요청을 보내고 응답을 기다린 후 결과를 반환합니다 (비동기 처리는 `WebClient` 추천).
- **HTTP 메서드 지원**: GET, POST, PUT, DELETE 등 모든 표준 HTTP 메서드 지원.
- **유연성**: 요청 헤더, 바디, 응답 타입 등을 커스터마이징 가능.
- **스프링 통합**: 스프링의 의존성 주입과 설정을 활용해 쉽게 사용.
#### 2. 의존성
`RestTemplate``spring-boot-starter-web`에 포함되어 별도 의존성 추가 없이 사용 가능합니다.
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
---
#### 3. 기본 설정
`RestTemplate`은 스프링 빈으로 등록해 사용할 수 있습니다. 기본 설정은 스프링 부트가 자동으로 제공하지만, 필요 시 커스터마이징 가능합니다.
```java
@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 요청
```java
@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 요청
```java
public User createUser(User user) {
String url = "https://api.example.com/users";
return restTemplate.postForObject(url, user, User.class);
}
```
- **`postForObject`**: 요청 바디에 객체를 보내고 응답 객체 반환.
- **참고**: JSON 직렬화는 `Jackson` 라이브러리에 의존 (기본 포함).
##### (3) PUT 요청
```java
public void updateUser(Long id, User user) {
String url = "https://api.example.com/users/{id}";
restTemplate.put(url, user, id);
}
```
- **`put`**: 응답 본문이 필요 없는 업데이트 작업.
##### (4) DELETE 요청
```java
public void deleteUser(Long id) {
String url = "https://api.example.com/users/{id}";
restTemplate.delete(url, id);
}
```
- **`delete`**: 리소스 삭제 요청.
##### (5) 커스텀 요청 (exchange)
```java
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 사용:
```java
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;
}
```
- **커스텀 에러 핸들러**:
```java
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 통신을 빠르게 구현할 수 있습니다. 추가 질문이 있다면 언제든 물어보세요!