💡 OpenFeign 란?
- 개념
Rest Call을 추상화 한Spring Cloud Netflix라이브러리
선언적인 HTTP 클라이언트를 제공하는 라이브러리- 사용방법
1. 호출하려는 HTTP Endpoint에 대한 interface 생성
2.@FeignClient선언
➡ Spring Boot 애플리케이션에서 Feign 클라이언트를 활성화하는 어노테이션- Load Balanced 지원
- 장점
1. 코드의 간결성
2. 유지보수성 향상
3. 효율적인 통합
4. MSA에 적합
➡ 서비스 등록/검색(Eureka), 로드 밸런싱(Ribbon), 장애처리(Hystrix)와 잘 통합되기 때문에 마이크로서비스 환경에서 다른 서비스와의 통신을 손쉽게 설정하고 관리 가능
User-service의 pom.xml 수정<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
package com.example.euserservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //추가
public class EUserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EUserServiceApplication.class, args);
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
//Rest Template이 아닌 OpenFeign을 사용할 것이기 때문에 더 이상 사용하지 않음
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
//여기까지
}
package com.example.euserservice.client;
import com.example.euserservice.vo.ResponseOrder;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@FeignClient(name="order-service")
public interface OrderServiceClient {
@GetMapping("/order-service/{userId}/orders")
List<ResponseOrder> getOrders(@PathVariable String userId);
}
✅ 참고
interface는 모두public으로 사용해야 하기 때문에 굳이public을 명시하지 않아도 됨
💡 추가 설명
@FeignClient어노테이션을 사용한 인터페이스는order-service라는 이름의 서비스에서 GET/order-service/{userId}/orders요청을 처리하는 클라이언트 역할
//추가
OrderServiceClient orderServiceClient;
//수정
@Autowired
public UserServiceImpl(UserRepository userRepository, BCryptPasswordEncoder passwordEncoder, Environment env, RestTemplate restTemplate, OrderServiceClient orderServiceClient) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.env = env;
this.restTemplate = restTemplate;
this.orderServiceClient = orderServiceClient;
}
//변경
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity = userRepository.findByUserId(userId);
if(userEntity == null){
//로그인 인증 시 사용하는 것이나, 사용자가 없다는 비슷한 의미로 해당 예시에서 사용
throw new UsernameNotFoundException("User not found");
}
UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
// List<ResponseOrder> orders = new ArrayList<>();
/* Using as rest template */
// String orderUrl = String.format(env.getProperty("order_service.url"), userId);
// ResponseEntity<List<ResponseOrder>> orderListResponse = restTemplate.exchange(orderUrl, HttpMethod.GET, null,
// new ParameterizedTypeReference<List<ResponseOrder>>() {
// });
//
// List<ResponseOrder> orderList = orderListResponse.getBody();
/* End */
/* Using as FeignClient */
List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
/* End */
userDto.setOrders(orderList);
return userDto;
}
✅ 참고
Rest Template을 사용하기 위해 추가했던Environmnet와restTemplate는 불필요(=미사용)
주문

주문내역 확인
