본문 바로가기

Programming!

Spring Boot 3.2 RestClient

https://spring.io/blog/2023/07/13/new-in-spring-6-1-restclient

 

New in Spring 6.1: RestClient

Spring Framework 6.1 M2 introduces the RestClient, a new synchronous HTTP client. As the name suggests, RestClient offers the fluent API of WebClient with the infrastructure of RestTemplate. Fourteen years ago, when RestTemplate was introduced in Spring Fr

spring.io

1. 일반적인 구현

 

Bean 등록

    ...
    @Bean
    fun fakeClassRestClient(): RestClient {
        return RestClient.builder().baseUrl("https://dummy-json.mock.beeceptor.com")
            .requestFactory(requestFactory())
            .defaultHeaders { headers: HttpHeaders ->
                headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                headers.set("header-custom", "9999-9999-1234")
            }
            .build()
    }
    ...

 

Service

@Service
class FakeClassRestClientService(
    private val fakeRestClient: RestClient
) {
    fun posts(): List<Post> {
        return fakeRestClient.get()
            .uri("/posts")
            .retrieve()
            .body(object : ParameterizedTypeReference<List<Post>>(){})!!
    }

    fun post(): Post {
        return fakeRestClient.get()
            .uri("/posts/1")
            .retrieve()
            .body(object : ParameterizedTypeReference<Post>(){})!!
    }
}

 

Test

@SpringBootTest(classes = [SpringBootEduApplication::class])
class FakeClassRestClientServiceTest(
    sut: FakeClassRestClientService
) : StringSpec(
    {
        val log = KotlinLogging.logger {}

        "RestClient 목록 조회" {
            val posts = sut.posts()
            log.info{posts}
            posts.size shouldBeGreaterThan 0
        }

        "RestClient 단건 조회" {
            val post = sut.post()
            log.info{post}
            post shouldNotBe null
        }
    }
)

 

 

2. 인터페이스 기반

설정

    @Bean
    fun fakeRestClientService(): FakeRestClientService {
        val client = RestClient.builder().baseUrl("https://dummy-json.mock.beeceptor.com")
			.requestFactory(requestFactory())
			.defaultHeaders { headers: HttpHeaders ->
                headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                headers.set("header-custom", "9999-9999-1234")
            }
            .build()
        val factory = HttpServiceProxyFactory
            .builderFor(RestClientAdapter.create(client))
            .build()
        return factory.createClient(FakeRestClientService::class.java)
    }

 

인터페이스

interface FakeRestClientService {
    @GetExchange("/posts")
    fun posts(): List<Post>

    @GetExchange("/posts/1")
    fun post(@RequestParam id: Long): Post
}

 

Test

@SpringBootTest(classes = [SpringBootEduApplication::class])
class FakeRestClientServiceTest(
    sut: FakeRestClientService
) : StringSpec(
    {
        val log = KotlinLogging.logger {}

        "RestClient 목록 조회" {
            val posts = sut.posts()
            log.info{posts}
            posts.size shouldBeGreaterThan 0
        }

        "RestClient 단건 조회" {
            val post = sut.post(1)
            log.info{post}
            post.id shouldBe 1
        }
    }
)

https://github.com/KimHyeongi/spring-boot-edu

 

 

GitHub - KimHyeongi/spring-boot-edu: spring boot 이것저것

spring boot 이것저것 . Contribute to KimHyeongi/spring-boot-edu development by creating an account on GitHub.

github.com