본문 바로가기

공부 정리/Java

RestTemplate

728x90
반응형

RestTemplate이란?

 

RestTemplate은 클라이언트 사이드에서 동기적인 HTTP 요청을 하는 클래스이다. Spring JdbcTemplate과 마찬가지로, HTTP client에 기반을 둔다. HTTP client 라이브러리는 다른 서버로 request를 보내 response 받아 데이터를 처리하는 기능이 있으며 RestTemplate 이외에 JDK HttpURLConnection, Apache HttpComponents 등이 있다.

 

RestTemplate의 장점

RestTemplate은 기본적으로 HttpUrlConnection으로 구현되어 있다. HttpUrlConnection이나 다른 HTTP client API를 사용하면, 요청을 할 떄마다 같은 상용구 코드가 계속 또 계속 반복등장한다.

 

  • URL 객체 생성 및 연결
  • HTTP 요청 설정
  • HTTP 요청 실행
  • HTTP response 해석
  • HTTP response를 자바 객체로 변환
  • 핸들링 실행

 

 RestTemplate은 고수준 API이므로, 위의 모든 과정을 백그라운드에 처리되도록 하고 개발자는 반복적 코드 작성을 피할 수 있다.

RestTemplate의 한계

 NOTE : Spring 5.0버전에서 WebFlux와 함께 WebClient라는 새로운 HTTP client가 등장했다. RestTemplate의 최신 대안 HTTP client이다. 동기, 비동기, 스트리밍과 최신 API를 가지며 풀 네임은org.springframework.web.reactive.client.WebClient 이다. RestTemplate  클래스는 유지보수 모드에 있으며, 앞으로는 변경 및 버그에 대한 사소한 요청만 허용될 예정이다. 또한 버전이 지날수록 deprecated 될 예정이다.

 

RestTemplate은 많은 메서드를 가지고 있는데, 이 글에서는 대표적으로 post요청을 소개한다.

 

RestTemplate exchange(post 요청 예제)

 

exchange 메서드 매개변수 첫번째는 내가 보낼 URI 정보를 두번째는 리턴받을 타입을 적는다.

 

*exchange 작성 방법

  1. URI 만들기(UriComponentBuilder 이용)
  2. RequestEntiy 만들기
  3. exchange 사용하기
@Service
class RestTemplateService {
 public UserResponse exchange() {
  URI uri = UriComponentBuilder
              .fromUriString("http://localhost:9090")
              .path("/api/server/user/{userId}/name/{userName}")
              .queryParam("name","aaaa")
              .queryParam("age",99)
              .encode()
              .build()
              .expand(100)
              .expand("steve")
              .toUri();

 //http body -> object -> object mapper -> json -> rest template -> http body json
  UserRequest req = new UserRequest("steve", 10);
  
  RequestEntity<UserReqeust> requestEntity = RequestEntity
        .post(uri)
        .contentType(MediaType.APPLICATION_JSON)
        .header("x-authorization", "abcd")
        .header("custom-header", "fffff")
        .body(req);

  RestTemplate restTemplate = new RestTemplate();
  ResponseEntity<UserResponse> response = restTemplate.exchange(requestEntity, UserResponse.class);
  
  return result.getBody();
 }
}

 Uri는 단순히 new URI()으로 만들수도 있지만, 변경가능성을 고려하여 UriComponentBuilder를 사용한다.

 

 RequestEntity에 post(uri)로 POST요청에 uri 주소를 넣는다. 또한 contentType, header, body를 지정할 수 있다.

UserRequest 클래스로 만든 객체를 body에 넣어준다. body에 UserRequest 객체를 넣었기 때문에 RequestEntity<UserReqest>를 타입으로 두었다.

 

 RequestEntiy 객체를 exchange의 첫번째 매개변수로 넣고, 리턴받을 UserResponse.class를 두번째 매개변수로 넣는다. 리턴받을 타입이 UserReponse이기 때문에 당연히 ResponseEntity<UserResponse>로 타입을 둔다. ResponseEntity 타입으로 리턴받으면 좋은점은 상태코드, 헤더정보 등도 조회가 가능하다.

 

PostForEntity() vs PostForObject()

RestTemplate의 대표적인 exchange, execute 이외에 postForEntiy와 PostForObject 메서드가 있다. postForEntity()는 ResponseEntity 객체를 리턴받는 다는 것이 차이점이고 기능은 같다.

 

 

 

postForEntity() 혹은 postForObject()를 사용하면 HttpEntity<?>가 아닌 Object 리턴형으로 req를 간단하게 보낼 수 있다.

public UserResponse post() {
  URI uri = UriComponentBuilder
              .fromUriString("http://localhost:9090")
              .path("/api/server/user/{userId}/name/{userName}")
              .queryParam("name","aaaa")
              .queryParam("age",99)
              .encode()
              .build()
              .expand(100)
              .expand("steve")
              .toUri();

 //http body -> object -> object mapper -> json -> rest template -> http body json
  UserRequest req = new UserRequest("steve", 10);

  RestTemplate restTemplate = new RestTemplate();
  //uri주소에 req를 보내서 UserResponse 타입을 받는다
  ResponseEntity<UserResponse> result = restTemplate.postForEntity(uri, req, UserResponse.class);
  
  return result.getBody();
 }
}

 

postForEntity에도 HttpEntity<>를 이용해서 header 정보를 넣을 수 있다.

public ResponseEntity<Employee> postForEntity(Employee newEmployee) {
  MultiValueMap<String, String> headers = new HttpHeaders();
  headers.add("User-Agent", "EmployeeRestClient demo class");
  headers.add("Accept-Language", "en-US");
  HttpEntity<Employee> entity = new HttpEntity<>(newEmployee, headers);
  return restTemplate.postForEntity(REQUEST_URI, entity, Employee.class);
}

 

출처

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

 

https://springframework.guru/using-resttemplate-in-spring/

 

https://www.baeldung.com/rest-template

 

 

 

 

728x90
반응형

'공부 정리 > Java' 카테고리의 다른 글

jar war 차이점  (0) 2022.04.26
자바 비동기  (0) 2021.08.16
Filter vs Interceptor 차이 (Spring)  (0) 2021.08.13
Validation 어노테이션 직접 만들어보기  (0) 2021.08.12
@Qualifier & @Resource & @Autowired  (0) 2021.08.12