Light Blue Pointer
본문 바로가기
Developing/TIL(Develop)

[Kotlin] RestClient를 MSA로 구성된 Spring module간 통신에 사용하는 예시

by Greedy 2024. 4. 25.

core module에 다음과 같은 interface를 생성한다

package kpring.core.auth.client

interface AuthClient {
    @PostExchange("/api/v1/validation")
    fun validateToken(
        @RequestHeader("Authorization") token: String,
    ): ResponseEntity<TokenValidationResponse>
}

 

chat module에서 auth module의 api를 호출하기 위해 core module의 interface를 사용한다

interface를 넘겨주면 HttpServiceProxyFactory 가 요청을 날리는 proxy를 생성한다

package kpring.chat.config

@Configuration
class ClientConfig {
    @Value("\\${auth.url}")
    private val authUrl: String? = null

    @Bean
    fun authClient(): AuthClient {
        val restClient = RestClient.builder()
            .baseUrl(authUrl!!)
            .build()
        val adapter = RestClientAdapter.create(restClient)
        val factory = HttpServiceProxyFactory.builderFor(adapter).build()
        return factory.createClient(AuthClient::class.java)
    }
}

 

원래는 authClient 객체를 Controller에 주입을 하려 해도 구현체가 없어서 되지 않는데 저 Config 파일을 설정해주면 저걸로 생성이 되어서 자동으로 주입된다!

package kpring.chat.api.v1

@RestController
@RequestMapping("/api/v1")
class ChatContoller(
    private val chatService: ChatService, val authClient: AuthClient
) {

    @PostMapping("/chat")
    fun createChat(
        @Validated @RequestBody request: CreateChatRequest, @RequestHeader("Authorization") token: String
    ): ResponseEntity<*> {
        val tokenResponse = authClient.validateToken(token)
        val userId = tokenResponse.body?.userId ?: throw GlobalException(ErrorCode.INVALID_TOKEN_BODY)

        val result = chatService.createChat(request, userId)
        return ResponseEntity.ok().body(result)
    }
}