[Spring] open feign으로 http client 통신하기 (1)

들어가며

spring cloud에 넷플릭스가 http client binder 관련해서 오픈소스 내놓은 open feign을 이용해서 RestTemplate을 대체 해보자

Project setting

  • spring boot : 2.2.6
  • lombok
  • spring web
  • spring cloud open feign
  • kotlin

Gradle setting

extra["springCloudVersion"] = "Hoxton.SR3"

dependencies {
    ...
    implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
    ...
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
    }
}
  • open feign을 사용하기 위해서는 spring cloud starter openfeign 라이브러리를 추가해야 한다.

open feign setting

@EnableFeignClients
@SpringBootApplication
class OpenFeignApplication

fun main(args: Array<String>) {
    runApplication<OpenFeignApplication>(*args)
}
  • @EnableFeignClients을 추가해야 @FeignClient 어노테이션이 붙어 있는 Client를 bean으로 등록해 준다.
  • ComponentScan을 통해서 annotation을 scan하기 때문에 root가 아닌 경우 basePackages를 설정 해야 한다.

open feign client

@Configuration
class LoggingConfiguration {
    @Bean
    fun feignLoggerLevel(): Logger.Level {
        return Logger.Level.FULL
    }
}
@FeignClient(name = "example", url = "http://localhost:8080", configuration = [LoggingConfiguration::class])
interface ExampleClient {

    @GetMapping("/success")
    fun success(): String

    @GetMapping("/success/{id}")
    fun successById(@PathVariable(name = "id") id: Long): String

    @GetMapping("/success/queryMap")
    fun successQueryMap(@SpringQueryMap params: Params): String
}
  • name은 해당 client를 식별하는데 사용되며, 만약 같은 name을 사용하고 싶은 경우 contextId 값을 통해서 유니크 문제를 해결할 수 있다.
  • url을 통해서 호출하고자 하는 server를 지정할 수 있으며, property injection이 가능하다
  • configuration에 특정 Configuration을 지정할 수 있다.
  • feign의 가장 큰 특징은 spring에서 사용하는 @GetMapping, @PostMapping @RequestMapping 등 을 그대로 사용할 수 있어 spring을 사용하는 사용자들은 이해하기 쉽다.
  • Logger.level.FULL로 하게 되면 상세한 logging을 볼 수 있다.
[ExampleClient#success] ---> GET http://localhost:8080/success HTTP/1.1
[ExampleClient#success] ---> END HTTP (0-byte body)
[ExampleClient#success] <--- HTTP/1.1 200 (136ms)
[ExampleClient#success] connection: keep-alive
[ExampleClient#success] content-length: 7
[ExampleClient#success] content-type: text/plain;charset=UTF-8
[ExampleClient#success] date: Sat, 18 Apr 2020 07:57:34 GMT
[ExampleClient#success] keep-alive: timeout=60
[ExampleClient#success] 
[ExampleClient#success] success
[ExampleClient#success] <--- END HTTP (7-byte body)

test

@SpringBootTest
class OpenFeignApplicationTests(@Autowired private val exampleClient: ExampleClient) {

    @Test
    fun successTest() {
        val success = exampleClient.success()

        assertThat(success).isEqualTo("success")
    }

    @Test
    fun successByIdTest() {
        val success = exampleClient.successById(1234L)

        assertThat(success).isEqualTo("1234")
    }

    @Test
    fun successQueryMapTest() {

        val success = exampleClient.successQueryMap(Params("test1", "test2"))

        assertThat(success).isEqualTo("test1 + test2")
    }

}
  • mock server를 사용하지 않고 local에 server를 띄워서 테스트를 진행
  • FeignClient로 만들어 두었던 response에 맞게 결과가 반환되어 사용하는데 있어서 간단하고 생각한다.

마치며

아주 기초적인 호출하는 방법과 @PathVariable, @RequestParam 정도에 대해서 알아 보았다.

error handling이나 retryable 등 좀 더 다양한 기능을 지원하고 있어 해당 부분은 다음 글에서 정리하려고 한다.

참고


Open Feign 관련 example code는 github에 올려두었으니 참고~!

Leave a comment