📝RestTemplate vs WebClient vs OpenFeign
RestTemplate
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://example.com/api", String.class);
블로킹 방식으로 직관적이고 사용법이 간단합니다. Spring 5 이후로는 Deprecated되었습니다.
WebClient
// Non Block 예제
WebClient webClient = WebClient.create();
Mono<String> result = webClient.get() // Mono는 0~1개의 비동기 응답을 감싸는 리액티브 타입
.uri("http://example.com/api")
.retrieve()
.bodyToMono(String.class);
// Block 예제
String response = webClient.get()
.uri("/posts/1")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class)
.block(); // <---- 블로킹 호출
Spring 5부터 제공되는 논블로킹 HTTP 클라이언트로 Mono, Flux등을 사용해 비동기 데이터 스트림을 처리합니다. 기본적으로 Spring WebFlux에 가장 잘 맞습니다. 물론 Blocking처리도 가능합니다.
OpenFeign
OpenFeign은 Spring Cloud에서 제공하는 HTTP 클라이언트로 마이크로서비스 간의 REST API 통신을 간편하게 만들어주는 라이브러리입니다. (MSA에 적절한 시스템)
@FeignClient(name = "payment-service") // Eureka에 등록된 서비스 이름
public interface PaymentClient {
@PostMapping("/payments")
PaymentResponse makePayment(@RequestBody PaymentRequest request);
@GetMapping("/payments/{id}")
PaymentResponse getPayment(@PathVariable("id") Long id);
}
Spring Cloud의 모듈 Eureka를 쓰는 경우 name으로 서비스 와 매핑을 시킬 수 있습니다.
@FeignClient(name = "payment-service", url = "http://localhost:8082")
public interface PaymentClient {
@PostMapping("/payments")
PaymentResponse makePayment(@RequestBody PaymentRequest request);
}
Eureka를 안 쓴 방식으로 http://localhost:8082/payments HTTP 요청합니다.
Eureka를 안 쓴 방식을 택할 수 있지만 Spring Cloud을 고려하고 만든 HTTP Client이기 때문에 Eureka와 같이 쓰는게 깔끔하게 떨어집니다.
📝HttpHeader
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Bearer token");
HTTP 요청 또는 응답에 포함되는 헤더 정보를 관리하는 클래스입니다.
📝HttpEntity
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{\"key\":\"value\"}", headers);
// Entity기반으로 Request 요청
String response = restTemplate.postForObject(
"https://httpbin.org/post",
entity,
String.class
);
HTTP 요청과 응답의 헤더와 바디를 캡슐화하는 클래스로 HTTP 메시지를 하나의 객체로 표현합니다.
Request Body의 내용과 Header를 같이 설정할 수 있습니다.
일반적으로 해당 Entity를 상속받은 RequestEntity나 ResponseEntity로 작업합니다.
📝ResponseEntity
@GetMapping("/response")
public ResponseEntity<String> getResponse() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "example");
return new ResponseEntity<>("This is response body", headers, HttpStatus.CREATED);
}
HttpEntity를 상속받아 반환값, 헤더값, 상태코드까지 표현하는 클래스입니다.
📝RequestEntity
RestTemplate restTemplate = new RestTemplate();
RequestEntity<String> request = RequestEntity
.post(new URI("https://httpbin.org/post"))
.header("Authorization", "Bearer token")
.body("{\"key\":\"value\"}");
ResponseEntity<String> response = restTemplate.exchange(request, String.class);
HttpEntity를 상속받아 반환값, 헤더값, 상태코드까지 표현하는 클래스입니다.
📝HttpStatus
return new ResponseEntity<>("Resource not found", HttpStatus.NOT_FOUND);
HTTP 응답코드로 (200, 404, 500 등)을 정의한 클래스입니다.