HTTP Interface 구현하기
다음은 HTTP Interface에 대한 설명입니다.
Spring에서의 REST Api, Http 요청, Method Parameter, Return Values, HttpExchangeInterface X2BEE 공통 커스텀 어노테이션에 대해 설명합니다.
설명
Spring 6.0 (SpringBoot3.0) 부터는 REST API 통신으로 쓰이는 HTTP Interface가 추가 되었습니다. spring-cloud에 있는 FeignClient와 사용법이 유사합니다. spring-data-*의 데이터 인터페이스와 비슷하게 인터페이스를 통해 REST API endpoint를 통해 데이터 통신을 하는 구조입니다.
Spring에서 REST Api 지원 역사는 아래와 같습니다.
Spring 3.0 → RestTemplate (앞으로 deprecated될 예정이므로 사용X)
Spring 5.0 → WebFlux의 WebClient
Spring 6.0 → HTTP Interface (내부적으로 WebClient 사용)
FeignClient와 다른 점은 각 endpoint의 BASE URL을 WebClient에 선언하고 해당 인터페이스가 Bean으로 등록되어야 하는 점입니다. 이는 Spring에서 명시적으로 endpoint를 집중해서 관리하려는 의미이기도 합니다.
역자 주) FeignClient의 편리함에 익숙해져 있다면 다소 불편하게 느껴질 수도 있습니다.
아래는 WebClient와 HttpServiceProxyFactory를 사용해 인터페이스를 Bean으로 등록하는 예시입니다.
@Configuration
public class HttpConfig {
@Bean
RepositoryService repositoryService() {
WebClient client = WebClient.create("https://jsonplaceholder.typicode.com");
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
RepositoryService service = factory.createClient(RepositoryService.class);
return service;
}
}위 코드에 대한 RepositoryService 코드는 아래와 같습니다.
여러 개의 REST Api endpoint를 관리하기 위해서는 아래와 같은 모양이 됩니다.
서비스 인터페이스 예시:
Http 요청
@GetExchange
HTTP GET requests
@PostExchange
HTTP POST requests
@PutExchange
HTTP PUT requests
@PatchExchange
HTTP PATCH requests
@DelectExchange
HTTP DELETE requests
Method Parameter
URI
annotation의 url을 덮어쓰고, 동적으로 요청의 URL을 설정한다.
HttpMethod
annotation의 method를 덮어쓰고, 동적으로 요청의 HTTP 메서드를 설정한다.
@RequestHeader
요청에 헤더를 추가한다. Map<String, ?> 또는 여러값인 경우 MultiValueMap<String, ?>, Collection<?>, 단일 값을 사용한다. 문자열이 아닌 경우에는 타입변환이 일어난다.
@PathVariable
URL에 포함된 path variable을 추가한다. 단일 값을 쓰거나, 여러 인자가인 경우 Map<String, ?>을 사용할 수 있다. 문자열이 아닌 경우에는 타입변환이 일어난다.
@RequestBody
serialize 될 객체 또는 Mono, Flux 같은 Publisher 또는 ReactiveAdapterRegistry에 의해 지원하는 비동기 타입의 어느 값을 body 제공한다.
@RequestParam
요청에 파라미터를 추가한다. Map<String, ?> 또는 여러값인 경우 MultiValueMap<String, ?>, Collection<?>, 단일 값을 사용한다. 문자열이 아닌 경우에는 타입변환이 일어난다. Content-type이 application/x-www-form-urlencoded로 설정되어 있으면, 요청의 파라미터는 body로 encode 된다. 그 외의 경우는 url 쿼리 파라미터로 추가된다.
@RequestPart
문자열, Resource(org.springframework.http.codec.multipart.FilePart), Object(JSON 같은 값으로 encode 될 엔티티), HttpEntity(part의 콘텐츠와 헤더), Part(org.springframework.http.codec.multipart), 위의 값들을 가진 Publisher를 멀티파트의 한 파트를 추가한다.
@CookieValue
쿠키 값을 추가한다. Map<String, ?> 또는 여러값인 경우 MultiValueMap<String, ?>, Collection<?>, 단일 값을 사용한다. 문자열이 아닌 경우에는 타입변환이 일어난다.
Return Values
void, Mono
요청을 수행하고, 응답의 콘텐츠를 버린다.
HttpHeaders, Mono
요청을 수행하고, 응답의 콘텐츠를 버리고 응답의 헤더를 리턴한다.
, Mono
요청을 수행해고, 응답을 주어진 리턴타입으로 decode 한다.
, Flux
요청을 수행하고, 응답을 주어진 리턴타입의 스트림으로 decode 한다.
ResponseEntity, Mono<ResponseEntity>
요청을 수행하고, 응답의 콘텐츠를 버린다. 그리고 ResponseEntity를 상태와 헤더와 함께 리턴한다.
ResponseEntity, Mono<ResponseEntity>
요청을 수행하고, 응답을 주어진 리턴타입으로 decode한다. 그리고 ResponseEntity를 상태와 헤더, 그리고 decode 된 body와 함께 리턴한다.
Mono<ResponseEntity<Flux>>
요청을 수행하고, 응답을 주어진 리턴타입의 스트림으로 decode한다. 그리고 ResponseEntity를 상태와 헤더, 그리고 decode 된 body 스트림과 함께 리턴한다.
HttpExchangeInterface (X2BEE 공통 커스텀 어노테이션)
위 설명에서와 같이 REST Api endpoint를 관리하기 위해서는 WebClient 설정을 Bean으로 등록하여 사용하여야 합니다. X2BEE에서는 해당 endpoint 관리를 편리하게 하기 위해서 HttpExchangeInterface 커스텀 어노테이션을 지원합니다.
HttpExchangeInterface.java (개요)
해당 어노테이션은 다음과 같은 항목들을 제공합니다.
baseUrl
Api endpoint url 설정값으로 Bean으로 등록하기 위하여 필수값임. 참고로 그냥 String값을 사용하면 해당값이 그대로 사용되고 ${app.apiUrl.event}와 같은 형태로 사용되면, application.yml에 등록된 환경변수값을 env.getProperty("app.apiUrl.event"); 같은 형태로 가져와 사용합니다.
defaultPath
해당 Api 서버의 ContextPath값으로 해당값이 있을 경우 baseUrl과 합쳐서 사용함. 해당값 역시 baseUrl과 동일하게 ${default.path} 형태를 제공합니다.
responseTimeoutSeconds
Http Client의 Response Timeout 설정값으로 기본값은 0 입니다.
connectionTimeoutSeconds
Http Client의 Connection Timeout 설정값으로 기본값은 10 입니다.
enableTokenAuth
헤더값에 Auth 토큰값을 포함할지 여부로서 기본값은 true입니다. 해당값은 기존 공통 RestApi Class의 enableTokenAuth값 함수를 그대로 가져왔습니다.
useMemberToken
헤더값에 로그인 사용자 토큰값을 포함할지 여부로서 기본값은 false입니다. 해당 옵션은 enableTokenAuth값이 true일때만 동작합니다. 기존 공통 RestApi Class의 useMemberToken값 함수를 그대로 가져왔습니다.
예시 인터페이스 사용:
위 예제와 같이 interface class에 @HttpExchangeInterface 어노테이션을 붙여줍니다.
해당 어노테이션이 있을 경우 스프링 시작 시점에 모든 패키지의 Class 파일을 검사하여 @HttpExchangeInterface이 붙은 Class 파일을 찾아 해당 어노테이션의 설정값으로 WebClient를 생성하고 Bean으로 등록해 줍니다.
사용 예시:
실행 시 enableTokenAuth 값이 true일 경우 헤더에 Authorization 값 또한 정상적으로 포함되어 요청이 전송되는 것을 확인할 수 있습니다.

마지막 업데이트