MSA간의 통신(2) FeignClient

·2024년 9월 25일

🚩프로젝트

목록 보기
5/5

의도

이번에는 RestTemplate통신에서 FeignClient로 프로젝트에 필요한 로직을 직접 넣어 보며 업데이트 해보겠습니다.

1. FegnClient

Feign은 어노테이션 기반의 Web Service Client로,
어노테이션 방식으로 동작함에 따라 Web Service Client를 쉽게 구성할 수 있습니다.

Spring MVC을 지원하고, Spring Web에서 사용되는 HttpMessageConverters도 지원합니다.

요약하자면, OpenFeign은 어노테이션 기반으로 Spring MVC 및 HttpMesageConverters를 지원함에 따라 기존 Spring MVC에서 어노테이션 기반으로 HTTP 통신을 했던 방식과 유사하게 구현할 수 있습니다.

따라서 다른 방식과 비교해서 비교적 간단하게 구현이 가능합니다.

또한 Spring Cloud에서 제공되기 때문에 다른 기술들(Eureka, Circuit Breaker, Load Balancer)와 통합이 쉽습니다.

Rest Call을 추상화 한 spring Cloud Netfilx 라이브러리
사용 방법

  • 호출하려는 HTTP Endipoin에 대한 interface를 생성
  • feignclient 선언

Load Balanced 지원


2. FeignClient 적용

서비스 간 통신에 OpenFeign을 적용해봅시다.

2-1 Spring Cloud OpenFeign 의존성 추가

// openfeign
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '4.1.0'

2-2 Application적용(OpenFeig 활성화)

@SpringBootApplication
@EnableFeignClients
public class BankServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(BankServiceApplication.class, args);
    }

}
  • ch-bank 서비스 쪽의 실행 Application에 해당 어노테이션을 선언하여 활성화했습니다.

2-3 OpenFeign 인터페이스 작성

@FeignClient(name = "kb-bank")
public interface KbBankFeignClient {

    @PostMapping("/api/kb-bank/mydata")
    AccountInfoResponseListDTO connectMyDataKbBank(
        @RequestHeader(value = "Authorization") String tokenHeader);

    @GetMapping("/api/kb-bank")
    AccountInfoResponseListDTO getMyDataKbBank(
        @RequestHeader(value = "Authorization", required = false) String tokenHeader);
}

인터페이스를 생성하고, @FeignClient를 붙여서 활성화 해줍니다

메소드로는 통신할 kb-bank Controller API를 그대로 작성해줍니다.

  • @FeignClient name 옵션 : 통신할 서비스의 Eureka 등록 이름
  • @FeignClient path 옵션 : RequestMapping의 value와 동일 (공통 URI 추출)

2-4 서비스를 호출하는 쪽(ch-bank)에서 OpenFeign 인터페이스 사용하여 통신**

@Service
@RequiredArgsConstructor
public class ChalletBankServiceImpl implements ChalletBankService {

    private final ChalletBankRepository challetBankRepository;
    private final Environment env;
    private final JwtUtil jwtUtil;
    private final KbBankClient kbBankClient;
    
    @Override
    public MyDataBankAccountInfoResponseDTO getMyDataAccounts(String tokenHeader) {

        AccountInfoResponseListDTO kbBanks = kbBankFeignClient.getMyDataKbBank(tokenHeader);
        AccountInfoResponseListDTO nhBanks = nhBankFeignClient.getMyDataKbBank(tokenHeader);
        AccountInfoResponseListDTO shBanks = shBankFeignClient.getMyDataKbBank(tokenHeader);

        return getMyDataAccounts(kbBanks, nhBanks, shBanks);
    }
    
    private MyDataBankAccountInfoResponseDTO getMyDataAccounts(AccountInfoResponseListDTO kbBanks,
        AccountInfoResponseListDTO nhBanks, AccountInfoResponseListDTO shBanks) {
        return MyDataBankAccountInfoResponseDTO
            .builder()
            .kbBanks(kbBanks)
            .nhBanks(nhBanks)
            .shBanks(shBanks)
            .build();
    }
    
}
  • KbBankClient를 주입받아서 작성했던 API를 호출하면 통신해서 FeignResponse를 받을 수 있습니다!

2-5 타 은행조회 컨트롤러

@RestController
@RequestMapping("/api/ch-bank")
@Tag(name = "ChalletBankController", description = "챌렛 은행 컨트롤러")
@RequiredArgsConstructor
public class ChalletBankController {

    private final ChalletBankService challetBankService;

    @GetMapping("/mydatas")
    @Operation(summary = "마이데이터 조회", description = "마이 데이터 조회")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "201", description = "마이데이터 조회 성공"),
        @ApiResponse(responseCode = "400", description = "마이데이터 조회 실패", content = @Content(schema = @Schema(implementation = Exception.class))),
    })
    public ResponseEntity<MyDataBankAccountInfoResponseDTO> getMyDataBanks(
        @RequestHeader(value = "Authorization") String tokenHeader) {
        MyDataBankAccountInfoResponseDTO myDataAccounts = challetBankService.getMyDataAccounts(
            tokenHeader);
        return ResponseEntity.status(HttpStatus.OK).body(myDataAccounts);
    }
}

2-6 서비스 통신 테스트

  • 그림과 같이 kb-bank 내용을 ch-bank에서 받을 수 있었습니다

0개의 댓글