본문 바로가기
SPRING

[Spring] FeignClient 란 무엇일까?

by 킹명주 2023. 7. 17.

오늘은 현업에서 많이 사용하고 있는 FeignClient에 대해 소개해보려고 한다. 이론 뿐만 아니라 실습까지 진행하면서 개념을 숙지해보자~~ 그럼 출발!!


FeignClient를 도입한 이유는?

 

현재 우리 팀은 서비스 별로 관리를 하는 MSA를 채택하여 사용하고 있다. 

 

크게 서비스 별로 나눈 그림을 살펴보면 내가 개발하는 service가 따로 있고, 회사 내부적으로 사용하는 공통 OPEN API가 따로 있으며 마지막으로 외부 API가 있다.

 

이때, 로그인을 하기 위해서는 반드시 내부 OPEN API에서 Access Token을 받아와야 하는 구조이다. 그렇다면 어떻게 백엔드 통신 코드를 작성할 수 있을까?

크게 두가지로 RestTemplate 방식과 FeignClient 방식이 있다. 즉, FeignClient란 웹 서비스 간 통신을 간편하게 구현하기 위한 라이브러리라고 보면 된다. 

 

그런데 왜 우리팀은 RestTemplate를 사용하지 않고 FeignClient 방식을 사용할까?

 

1. 선언적 방식

필자는 이부분이 가장 중요하다고 생각한다. FeignClient를 구현하기 위해서는 인터페이스와 어노테이션을 활용하는데 이는 가독성 뿐만 아니라 코드 재사용에도 유리하다. 또한, @feignclient 이것 하나로 HTTP 통신은 끝이다.. 얼마나 간단한가?!

 

2. 로드 밸런싱 제공

해당 라이브러리는 Netfliex에서 개발한 것인데, 로드 밸런싱 기능을 자체적으로 제공한다고 한다. 

그러므로 대규모 서비스에 적용하기에도 적합하다.

 

3. 설정

설정 부분도 간단한데, configuration을 선언하여 Header에 넣을 값을 지정할 수 있으며 데이터 타입 등을 지정할 수 있다.

 


FeignClient 실습

 

자자~~ 이제 이론은 어느정도 적립되었을 것이다. 그냥 단순하게 "백엔드 통신에 필요한 라이브러리" 로만 기억해도 좋다.

실습으로 들어가보자~

요런식으로 매우 간단하게 실습을 해보고자 한다. 우선 localhost:8081에 해당하는 실습 파일을 간단하게 만들어준다.

@RestController
@RequestMapping("/mj-openapi")
public class TestController {

    @GetMapping("/hello")
    public String helloTest() {
        return "Hello World";
    }
}

해당 파일은 8081 포트를 사용하는 서비스로, 간단하게 /mj-openapi/hello에 get 요청을 하게되면 hello world를 반환하는 형태이다.

(* 참고 [port 지정 방법] : application.properties에서 server.port = 8081 한 줄 추가)

 

그렇다면 본격적으로 feign client 코드를 소개하고자 한다.

우선 가장먼저 해당 서비스의 build.gradle, Application 파일을 수정해야한다.

 

build.gradle

ext {
	springCloudVersion = '2021.0.3'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}
dependencies {
	implementation "org.springframework.cloud:spring-cloud-starter-openfeign"
}

요런식으로 기존의 dependencies에서 oepnfeign를 추가해준다.

 

DemoApplication

@SpringBootApplication
@EnableFeignClients
public class DemoApplication {

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

}

@EnableFeignClients << 요 부분이 핵심이다. 반드시 추가해야 한다.

 

프로젝트 구조는 요런식으로 작성을 했고 하나 하나씩 살펴보자!!

 

 

 

 

 

TestFeignClient

@FeignClient(name = "testFeignClient", url = "http://localhost:8081/mj-openapi")
public interface TestFeignClient {

    @GetMapping("/hello")
    String getHelloWorld();
    
}

@FeignClient 어노테이션을 활용했고, localhost:8081/mj-openapi/hello의 get 요청을 통해 String 형태로 결과를 받아오는 코드이다. 너무 간단해서 깜놀..

 

TestFeignController

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1")
public class TestFeignController {

    private final TestFeignService testFeignService;

    @GetMapping("/hello")
    public ResponseEntity<String> helloTest(){
        return ResponseEntity.ok(testFeignService.getHelloWorld());
    }
}

현업에서 되도록이면 feignClient를 호출하는 부분은 service 단으로 넘겨라 해서 그 구조를 따라서 작성해보자~ (이유는 잘모름 ㅎㅎ)

 

TestFeignService

@Service
@RequiredArgsConstructor
public class TestFeignService {

    private final TestFeignClient testFeignClient;

    public String getHelloWorld(){
        return testFeignClient.getHelloWorld();
    }
}

요렇게 모두 작성했다면 Test를 진행해보자

성공적으로 localhost:8081/mj-openapi/hello의 response를 받아오는 것을 확인할 수 있다.

 

가독성 측면이나 코드 재활용에 있어 매우 좋다고 생각을 하고있다. 아마 실습을 통해 더욱 느꼈을 것이라고 믿고있다.

 


결론

 

오늘은 feign client에 대해 알아보았다. 좀 더 세부적으로 나아간다면 configuration을 지정하거나 fallback을 지정하는 부분을 다룰 수 있다. 해당 부분은 필자도 아직 미숙하기 때문에 조금 더 연구가 필요하다~~~