@PostExchange, @GetExchange?

기존 코드를 읽다가 해당 어노테이션들을 발견했다. 인터페이스 메서드에 붙어 HTTP 요청을 수행하는데, 해당 어노테이션들은 인터페이스에만 붙을 수 있는 것인지, 어떤 개념인지 궁금해졌다. ChatGPT를 활용하여 선언적 HTTP 클라이언트 기능을 활용하기 위한 어노테이션이었음을 알게 되었고, 기록을 남겨둔다. 아래는 ChatGPT의 답변이다.

선언적 HTTP 클라이언트

선언적 HTTP 클라이언트 기능은 Spring Framework 6와 Spring Boot 3에서 도입된 기능으로, 웹 서비스와의 통신을 위한 클라이언트 코드를 보다 간결하고 선언적으로 작성할 수 있게 해 줍니다.

이 기능은 자바 인터페이스를 사용하여 HTTP 요청을 선언적으로 정의하고, Spring이 이를 구현하여 실제 HTTP 요청을 자동으로 처리하도록 해 줍니다. 이 접근 방식은 Feign 클라이언트와 유사하며, Spring Data의 저장소 인터페이스 방식을 HTTP 클라이언트에 적용한 것이라고 볼 수 있습니다.

선언적 HTTP 클라이언트의 주요 특징

  1. 인터페이스 기반의 클라이언트 정의: 사용자는 인터페이스를 정의하고, HTTP 메소드에 해당하는 어노테이션(@GetExchange, @PostExchange 등)을 메소드에 적용하여, 원하는 웹 서비스의 엔드포인트와 매핑합니다.
  2. 자동 프록시 생성: Spring은 정의된 인터페이스를 기반으로 HTTP 요청을 처리하는 프록시 객체를 자동으로 생성합니다. 이 프록시는 인터페이스 메소드 호출을 실제 웹 서비스 호출로 변환합니다.
  3. 유연한 매개변수 및 반환 형식 처리: 메소드 매개변수는 @PathVariable, @RequestBody, @RequestParam 등을 통해 동적으로 지정할 수 있으며, 반환 형식도 다양하게 지원하여 동기 또는 비동기(Reactive 타입 포함)로 처리할 수 있습니다.

사용 방법 예시

// HTTPExchange를 붙이지 않고 바로 메소드 별로도 붙일 수 있음
@HttpExchange(url = "/users", contentType = "application/json")
public interface UserClient {
    @GetExchange("/")
    List<User> getAllUsers();

    @PostExchange("/")
    User createUser(@RequestBody User user);

    @DeleteExchange("/{id}")
    void deleteUser(@PathVariable("id") Long id);
}

위 예시에서는 사용자 정보를 관리하는 기본적인 REST API 클라이언트 인터페이스를 보여줍니다. 각 메소드는 HTTP 메소드에 맞는 어노테이션을 사용하여 정의됩니다.

설정 및 구성

이 기능을 사용하기 위해서는 Spring Boot의 spring-boot-starter-webflux 의존성이 필요합니다. 이는 비동기 및 논블로킹 I/O를 지원하기 위해 Reactor 라이브러리와 함께 WebClient를 사용하기 때문입니다. 구성은 간단하며, 주로 WebClient 설정과 함께 시작됩니다.

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient() {
        return WebClient.builder().baseUrl("<http://example.com>").build();
    }
}

선언적 HTTP 클라이언트 기능은 개발자가 HTTP API와의 상호 작용을 간편하게 구현할 수 있게 해 줌으로써, 코드의 가독성과 유지 관리를 개선할 뿐만 아니라, 에러 처리 및 테스팅을 보다 체계적으로 할 수 있게 돕습니다. 이러한 접근 방식은 특히 마이크로서비스 아키텍처에서 서비스 간 통신을 구현할 때 매우 유용합니다.