최신의 API를 제공하는 동기식 HTTP클라이언트이다. 자바 객체에서 HTTP요청으로 편리하게 변환하고 HTTP응답에서 객체를 생성할 수 있도록 HTTP 라이브러리에 대한 추상화를 제공한다.
HTTP interface HTTP 서비스를 자바 인터페이스로 정의하고, HTTP 교환 메소드를 사용할 수 있는 기능을 제공한다. 그럼 이렇게 정의된 인터페이스를 구현하는 프록시를 생성할 수 있는데, 이 프록시가 실제로 HTTP 교환을 수행하게 된다.
Spring 에서 제공하는 4가지 Rest endpoints
RestClient 생성 - builder 방식을 추천
create() 메서드를 사용하는 방법
builder를 이용한 방법 - 굳이 빈으로 사용하지 않아도 된다.
@Bean
RestClient restClient(RestClient.Builder builder){
return builder
.requestFactory(new JdkClientHttpRequestFactory())
.messageConverters(converters->
converters.add(new MyCustomMessageConverter())).....
⭐ Http 통신을 하기 위해서는 HttpClient 라는 인터페이스가 필요
MessageConverters → 어떤 형식으로 통신할 건지( Rest ful → json, xml → 파싱 결정이 필요)
웅답 객체
RestClient 사용하기
restClient.get()
.uri("<https://example.com>")
.retrieve()
.body(String.class);
ResponseEntity<Void> response = restClient.post()
.uri("<https://petclinic.example.com/pets/new>")
.contentType(APPLICATION_JSON)
.body(pet)
.retrieve()
.toBodilessEntity();
String result = restClient.get()
.uri("<https://example.com/this-url-does-not-exist>")
.onStatus("HttpStatusCode::is4xxClientError,
(request, response) ->
{throw new MyCustomRuntimeException(response.getStatusCode(),
response.getHeaders()) })
.body(String.class);
Pet result = restClient.get()
.uri("<https://petclinic.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;} });
보통은 위와 같이 return 과 에러처리를 exchange()를 사용하여 한 번에 처리한다.
@HttpExchange
@HttpExchange("<https://example.com>")
interface RepositoryService {
@GetExchange("/repos/{owner}/{repo}"}
Repository get Repository(@PathVariable String owner,
@PathVariable String repo);
@Bean
RepositoryService repositoryPoxy(RestClient.Builder builder){
RestClient restClient = builder.baseUrl("<https://api.github.com/>").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(RepositoryService.class);
}
@Bean
RepositoryService repositoryKakaoPoxy(RestClient.Builder builder){
RestClient restClient = builder.baseUrl("<https://api.kakao.com/>").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(RepositoryService.class);
}
...
예제
https://velog.io/@gnivy303/Spring-boot-3.2에서-Rest-Clinet-와-HTTP-Interface-를-활용한-외부-API-호출
@Configuration
public class RestClientConfig{
@Bean
public AnyComponent anyService() {
RestClient restClient = RestClient.builder().baseUrl("<http://anything.co.kr>")
.build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(adapter)
.build();
return factory.createClient(AnyComponent.class);
}
}
RestClient restClient = RestClient.builder().baseUrl("http://anything.co.kr").build(); → RestClient객체 생성, 기본 URL설정, Http요청을 보내는 역할을 한다.
RestClientAdapter adapter = RestClientAdapter.create(restClient); → 이 Adapter는 RestClient의 기능을 확장하는 역할을 한다.
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(adapter).build(); → HttpServiceProxyFactory객체를 생성한다. 이 Factory는 Http서비스의 프록시 객체 생성 역할
Http Interface
@Component
@HttpExchange
public interface AnyComponent {
@GetExchange("/Search.aspx")
String findAllByQuery(@RequestParam String key, @RequestParam String value);
}
사용 예시
@Component
@RequiredArgsConstructor
public class ApiComponent {
private final AnyComponent anyComponent;
public ApiListResponse findListByKeyWordAndApi(){
JSONObject json = new JSONObject(anyComponent.findAllByQuery("anyKey", "anyValue");
}