Spring HTTP Call

insukL·2024년 3월 12일
0

서론

이전부터 RestTemplate를 아닌 새로운 방법을 사용해야겠다고 인지하고 있었는데, 새 프로젝트를 진행하면서 RestClient를 사용했다. 그 과정에서 여러 글을 참고했는데, 해당 포스팅은 그 글들을 모아 정리한 내용이다.

그래서 별다른 추가 내용을 적지 않아, 원 글들이 진짜 내용이라 생각해 참고를 먼저 작성했다.

참고

RestTemplate Deprecated

뭐? RestTemplate가 Deprecated라고?
RestTemplate Deprecated 루머 해결

RestClient

Spring 6.1 RestClient 공식문서
[Spring] Spring Boot3.2에 새롭게 추가될 RestClient
Api 보낼 때 RestTemplate, WebClient.. 그리고 RestClient?

Not RestTemplate

  • 엄밀히 말하자면, Deprecated 된 것은 아님
  • Spring 5가 나오면서 WebClient를 통해 RestTemplate를 대체하고자 함
    • RestTemplate가 Spring 3에서 출시되었는데, 이에 대해 오랜 시간이 흐르면서 사용되는 클래스가 많아졌다고 함
    • 이에 비동기를 지원하는 WebClient로 대체하고 했음

Not WebClient, Why?

  • WebClient가 나왔지만 RestTemplate가 자리 잡아 잘 사용하지 않았음
  • 비동기 요청을 진행하는 경우 block 메소드를 추가로 사용해야 한다
    • 해당 메소드를 사용하는 것은 안티 패턴으로 추천하지 않는다고 함..
  • WebClient를 사용하기 위해서는 아래를 오로지 WebClient를 사용하기 위해 추가해야 함
implementation 'org.springframework.boot:spring-boot-starter-webflux'
  • webflux 모듈은 Spring 5 부터 추가되었는데, 나중에 살펴보는 걸로…

RestClient의 등장

  • WebClient가 webflux를 사용해야 한다는 문제에서 기인하여 만들어진 서블릿 기반의 WebClient로 보면 됨

  • Spring 6.1, Spring Boot 3.2부터 사용 가능함

RestClient 사용하기

RestClient 객체 생성하기

RestClient restClient1 = RestClient.create();
RestClient restClient2 = RestClient.create(restTemplate);
RestClient restClient3 = RestClient.builder()
                .baseUrl("<https://example.com>")
                .build();

GET 요청

String result = restClient.get()
  .uri("https://example.com")
  .retrieve()
  .body(String.class);
  • 필요에 따라 Entity의 형태로 받을 수 있다
ResponseEntity result = restClient.get()
  .uri("<https://example.com>")
  .retrieve()
  .toEntity(String.class);
  • RestTemplate와 동일하게 Message Converter를 사용함
Pet pet = restClient.get()
  .uri("https://example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .retrieve()
  .body(Pet.class);

POST 요청

ResponseEntity<Void> response = restClient.post()
  .uri("https://example.com/pets/new")
  .contentType(APPLICATION_JSON)
  .body(pet)
  .retrieve()
  .toBodilessEntity();

Error 핸들링

String result = restClient.get()
  .uri("https://example.com/this-url-does-not-exist")
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders())
  })
  .body(String.class);

Exchange

  • 좀 더 자세한 설정을 위해 exchange 메소드 사용 가능
Pet result = restClient.get()
  .uri("<https://example.com/pets/{id}>", id)
  .accept(APPLICATION_JSON)
  .exchange((request, response) -> {
    if (response.getStatusCode().is4xxClientError()) {
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders());
    }
    else {
      Pet pet = convertResponse(response);
      return pet;
    }
  });
profile
데이터를 소중히 여기는 개발자가 되고 싶습니다

0개의 댓글