jujuwon
시크릿주주
jujuwon
전체 방문자
오늘
어제
  • 분류 전체보기 (106)
    • 🔠 프로그래밍언어 (35)
      • ☕️ Java (19)
      • 🐠 Python (15)
      • 🍠 Kotlin (1)
    • 🔙 Backend (16)
      • 🌿 Springboot (12)
      • 🐳 Docker (1)
      • ☁️ AWS (3)
    • 💼 CS (12)
      • 📶 Network (12)
    • 🕹 알고리즘 (14)
      • 📑 스터디 (2)
      • 💁🏻‍♂️ 백준 (9)
      • 👨🏼‍🔬 프로그래머스 (3)
    • 📚 Book (8)
      • 🔎 오브젝트 (4)
      • 🧪 TDD (2)
      • 📜 논문 (2)
    • 🔐 보안 (7)
      • 👾 Pwnable (7)
    • 📝 회고 (4)
    • 🧩 etc. (10)
      • ⚠️ issue (2)
      • 💡 꿀팁 (7)
      • ✏️ 끄적 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.
jujuwon

시크릿주주

Spring Boot :: @FeignClient 로 외부 REST API 간편 호출
🔙 Backend/🌿 Springboot

Spring Boot :: @FeignClient 로 외부 REST API 간편 호출

2022. 9. 21. 19:52
반응형

들어가면서


카카오 및 애플 로그인을 구현하면서 외부 API 서버에 접근해 데이터를 받아와야 하는 일이

많아졌고, API 주소를 설정파일에 저장한 후 직접 HttpURLConnection 을 생성해서

연결하는 코드가 중복되게 되었다.

또 직접 HttpURLConnection 을 연결해 외부 API 에서 데이터를 받아오면

받아온 JSON 을 직접 파싱해야 하는 불편함도 존재했다.

정리하자면,

  1. 외부 API 를 간편하게 호출하고 싶어서
  2. 호출 결과를 직접 파싱하는 과정이 번거로워서

FeignClient 를 사용하게 되었다.

아래 설명에서는 많이 예시를 드는 Github API 를 이용해서 코드를 작성해보았다.

FeinClient


Feign 은 Netflix 에서 개발한 REST Client 이다.

기존에 RestTemplate 을 사용한 API 호출 코드량을 줄이고 간편하게 호출할 수 있게 해준다.

먼저 FeinClient 를 이용하기 위해 필요한 세팅을 정리해보자. (Gradle 기준)

  • build.gradle 에 의존성 추가
  • FeignClient 인터페이스 생성
  • @EnableFeignClients 추가
  • FeignClient Config 정보 설정
  • Service 에 FeignClient 의존성 주입
  • Controller 에 FeignService 의존성 주입

build.gradle 의존성 추가


ext {
    set('springCloudVersion', "2021.0.1")
}

implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

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

FeignClient 인터페이스 생성


@FeignClient(name = "githubFeignClient", url = "https://api.github.com",
        configuration = GithubFeignClientConfig.class)
public interface GithubFeignClient {

    @GetMapping("/users/{githubId}")
    GithubUserResponse getGithubUser(@PathVariable("githubId") String githubId);

    @GetMapping("/search/commits?q=author:{author} committer-date:{committerDate}")
    GithubUserResponse getGithubCommits(@PathVariable("author") String author,
        @PathVariable("committerDate") String committerDate);
}

어노테이션 안에 들어가는 값들은 다음과 같다.

@FeignClient(name ="feign client 이름 설정" , url="호출할 api url", 
    configuration = "feignclient 설정정보가 셋팅되어 있는 클래스")

추가로 Github API 를 호출하고 받을 Response 를 Mapping 하는 DTO 를 정의하자.

@Data
@AllArgsConstructor
public class GithubUserResponse {
    String login;
    Long id;
    String node_id;
    String avatar_url;
}

@EnableFeignClients 추가


@EnableFeignClients
@Configuration
public class GithubFeignClientConfig {
}
  • Application Main 클래스 위에 @EnableFeignClients 를 추가해도 된다.

FeignClient Config 정보 설정


Config 클래스를 생성하고 필요한 설정 정보를 세팅할 수 있다.

  • Config 를 따로 생성하지 않아도 아래 Bean 들은 기본적으로 제공된다.

Spring Cloud OpenFeign provides the following beans by default for feign (BeanType beanName: ClassName):
Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)
Encoder feignEncoder: SpringEncoder
Logger feignLogger: Slf4jLogger
MicrometerCapability micrometerCapability: If feign-micrometer is on the classpath and MeterRegistry is available
CachingCapability cachingCapability: If @EnableCaching annotation is used. Can be disabled via feign.cache.enabled.
Contract feignContract: SpringMvcContract
Feign.Builder feignBuilder: FeignCircuitBreaker.Builder
Client feignClient: If Spring Cloud LoadBalancer is on the classpath, FeignBlockingLoadBalancerClient is used. If none of them is on the classpath, the default feign client is used.
  • 아래 Bean 들은 필요할 때 Config 클래스에 만들어주어야 한다.
Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection
SetterFactory
Capability (MicrometerCapability and CachingCapability are provided by default)

예시로, Github API 에서 유저를 조회했을 때 사용자가 없고,

해당 아이디를 가진 Github 유저가 없다 라는 커스텀 에러가 필요한 상황이라고 가정하자.

그럴 땐 에러 생성 후에 Config 에 ErrorDecoder 를 상속받은 GithubFeignError 를 작성하면 된다.

  • Config 클래스
@EnableFeignClients
@Configuration
public class GithubFeignClientConfig {

    @Bean
    public ErrorDecoder errorDecoder() {
        return new GithubFeignError();
    }
}
  • 커스텀 에러 클래스
public class GithubFeignError implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        switch (response.status()) {
            case 404:
                return new GithubUserNotFoundException();    // 커스텀 Exception
        }
        return null;
    }
}

Service 에 FeignClient 의존성 주입


@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class GithubFeignService {

    private final GithubFeignClient githubFeignClient;

    public GithubUserResponse getGithubUser(String githubId) {
        return githubFeignClient.getGithubUser(githubId);
    }
}

 

Controller 에 FeignService 의존성 주입


@RestController
@RequiredArgsConstructor
public class GithubController {

    private final GithubFeignService githubFeignService;

    @GetMapping("/github/user/{userId}")
    public GithubUserResponse getGithubUser(@PathVariable("userId") String userId) {
        return githubFeignService.getGithubUser(userId);
    }
}

이제 Spring 을 실행시키고 localhost:8080/github/user/{userId} 를 호출하면

Github 유저 정보가 나오는 것을 확인할 수 있다.

728x90
반응형
저작자표시 (새창열림)
    '🔙 Backend/🌿 Springboot' 카테고리의 다른 글
    • JUnit :: ParameterizedTest 로 경계값 테스트하기
    • JPA :: 벌크성 수정 쿼리
    • JPA :: 페이징과 정렬
    • JPA :: Query Method 기능
    jujuwon
    jujuwon

    티스토리툴바