Feign
- Netflix에서 개발된 http client binder이다.
- interface, annotation 작성만 하면 되므로 비교적 간단하게 구현할 수 있다.
- 동기 방식으로 동작한다.
시작하기
dependency
build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
Application.java
@SpringBootApplication
@EnableFeignClients
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) { SpringApplication.run(Application.class); }
}
위처럼 main 함수가 있는 클래스에 @EnableFeignClients 어노테이션을 붙여준다.
@EnableFeignClients는 지정된 패키지를 돌아다니면서 @FeignClient를 찾아 구현체를 만든다.
패키지는 basePackages 또는 basePackageClasses 를 통해 지정할 수 있다.
혹은 위 예시처럼 root package에 속성 없이 어노테이션을 붙이면 root package를 돌아다니면서 구현체를 만들어준다.
사용하기
@GetMapping
@FeignClient(name = "student", url = "http://~~~.co.kr")
public interface StudentApi {
@GetMapping(value = "/api/student/list")
ApiResponse getStudentList() throws Exception;
}
위는 예시이다.
이렇게 인터페이스로 구현하면 구현체는 자동으로 만들어준다.
GET 메소드로 호출하고 싶은 경우 @GetMapping 어노테이션을 사용한다.
호출하는 api의 응답에 맞게 받아오는 객체를 만들어서 받아주었다.
@FeignClient(name = "student", url = "http://~~~.co.kr")
public interface StudentApi {
@GetMapping(value = "/api/student/{studentId}")
ApiResponse getStudentByStudentId(@PathVariable("studentId") Long studentId) throws Exception;
}
@PathVariable 예시이다.
여기서 주의해야 할 점은 value 값을 넣어주어야 한다는 것이다.
controller를 작성할 때 보통 @PathVariable Long studentId 이런 식으로 하는데,
여기서는 @PathVariable("studentId") Long studentId 이렇게 value를 꼭 넣어주어야 한다.
@FeignClient(name = "student", url = "http://~~~.co.kr")
public interface StudentApi {
@GetMapping(value = "/api/student/{studentId}")
ApiResponse getStudentByStudentId(@PathVariable("studentId") Long studentId,
@RequestParam("filters") String filters ) throws Exception;
}
@RequestParam 예시이다.
비슷하게 넣어주면 된다.
나는 여기서 헤맸는데, 나의 경우에는 request parameter가 항상 고정적으로 똑같았기 때문에 쿼리 스트링을 GetMapping의 value에 쌩으로;; 넣어주었다.
이렇게 하면 제대로 받아오지 못하기 때문에 파라미터는 다 @RequestParam으로 넘겨주자.
@RequestMapping
@FeignClient(name = "student", url = "http://~~~.co.kr")
public interface StudentApi {
@RequestMapping(method = RequestMethod.GET, value = "/api/student/{studentId}")
ApiResponse getStudentByStudentId(@PathVariable("studentId") Long studentId,
@RequestParam("filters") String filters ) throws Exception;
}
위처럼 @RequestMapping에 메소드를 설정해줘서 할 수도 있다.
@PostMapping
@FeignClient(name = "student", url = "http://~~~.co.kr")
public interface StudentApi {
@PostMapping(value = "/api/student")
ApiResponse saveStudent(@RequestBody("StudentDto") String StudentDto) throws Exception;
}
Post 요청은 위와 같이 보낼 수 있다.
@RequestBody 어노테이션을 사용하여 요청의 body에 들어갈 것을 넣어주면 된다.
메소드를 작성할 때 파라미터에 아무 어노테이션도 붙이지 않으면 @RequestBody로 인식한다고 한다.
여기도 마찬가지로 value를 채워주긴 했는데, RequestBody는 value를 채우지 않아도 되는 듯.
추가적으로 header, configuration, errorDecoder, retry 등을 더 공부하고 적용해보고 싶다.
개인적으로 사용해 봤을 때는 RestTemplate이나 WebClient보다 간단하게 사용할 수 있었다.
WebClient가 꼭 필요한 경우가 아니라면 FeignClient를 사용해도 좋을 것 같다.
참고
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html
https://techblog.woowahan.com/2630/
https://www.baeldung.com/spring-boot-feignclient-vs-webclient
'Spring' 카테고리의 다른 글
assertThat() import가 안 될 때 해결 (0) | 2023.08.19 |
---|---|
Could not find org.projectlombok:lombok:.Required by: project : 에러 해결 (0) | 2023.07.31 |
JPA JPQL 파라미터 객체(Object)로 한 번에 넘기기 (0) | 2023.07.26 |
JPA ConverterNotFoundException: No converter found capable of converting from type 에러 해결 (0) | 2023.07.26 |
JPA 양방향 매핑 Entity 한 번에 저장하기 (0) | 2023.07.23 |