본문 바로가기

Android 공부/네트워크 통신

Ktor

Ktor

  • 코틀린으로 비동기 클라이언트 및 서버 앱을 작성할 수 있게 하는 Jetbrains에서 만든 코틀린 프레임워크
  • 코틀린 코루틴 기반으로 설계되어 비동기 처리 유리
  • iOS, Web 등 코틀린 지원 플랫폼에서 동일한 네트워킹 코드 사용 가능 -> 주로 KMP 프로젝트에서 사용
  • 리플렉션을 사용하는 Retrofit보다 속도가 빠르고 메모리 사용량이 적음
  • DSL 방식을 사용하여 보다 직관적
  • TimeOut 등 HttpClient에서 원하는 기능만 사용 가능
    import io.ktor.client.HttpClient
    import io.ktor.client.engine.android.Android
    import io.ktor.client.plugins.DefaultRequest
    import io.ktor.client.plugins.HttpTimeout
    import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
    import io.ktor.client.plugins.defaultRequest
    import io.ktor.client.plugins.logging.LogLevel
    import io.ktor.client.plugins.logging.Logger
    import io.ktor.client.plugins.logging.Logging
    import io.ktor.client.plugins.observer.ResponseObserver
    import io.ktor.client.request.accept
    import io.ktor.client.request.header
    import io.ktor.http.ContentType
    import io.ktor.http.HttpHeaders
    import io.ktor.http.contentType
    import io.ktor.serialization.kotlinx.json.json
    
    HttpClient(Android) {
        install(ContentNegotiation) {
            json(
                Json {
                    prettyPrint = true
                    isLenient = true
                    useAlternativeNames = true
                    ignoreUnknownKeys = true
                    encodeDefaults = false
                }
            )
        }
    
        install(HttpTimeout) {
            requestTimeoutMillis = NETWORK_TIME_OUT
            connectTimeoutMillis = NETWORK_TIME_OUT
            socketTimeoutMillis = NETWORK_TIME_OUT
        }
    
        install(Logging) {
            logger = object: Logger {
                override fun log(message: String) {
                    Log.v("Logger Ktor =>", message)
                }
            }
            level = LogLevel.ALL
        }
    
        install(ResponseObserver) {
            onResponse {
                response - >
                    Log.d("HTTP status:", "${response.status.value}")
            }
        }
    
        install(DefaultRequest) {
            header(HttpHeaders.ContentType, ContentType.Application.Json)
        }
    
        defaultRequest {
            contentType(ContentType.Application.Json)
            accept(ContentType.Application.Json)
        }
    }


  • 서비스에 API 요청 정의 - HttpClient와 Service를 분리하여 구현으며, interface로 정의 후, Impl로 구현하여도 문제 없다. get, post 등 HTTP 통신 전부 가능하며, query parameter의 경우 paramter()를 통해 넣어줄 수 있다.
    suspend fun getMealsByCategory(category: String) =
        client.get {
            url(getString(R.string.meals_url))
            parameter("c", category)
        }


  • 헤더를 추가할 때는 람다 안에 headers를 통해 추가할 수 있다
    client.get(URL) {
        headers {
            append(HttpHeaders.Authorization, "Bearer YOUR_TOKEN_HERE")
            append("Custom-Header", "MyValue")
        }
    }


  • body는 람다 안에 setBody()를 통해 @Seriablizable 객체를 넣어줌으로서 전달할 수 있다
    suspend fun createUser(user: User): HttpResponse {
        return client.post("https://api.example.com/users") {
            setBody(user) // @Serializable이 붙은 객체를 그대로 전달
        }
    }

'Android 공부 > 네트워크 통신' 카테고리의 다른 글

Retrofit  (0) 2026.02.21