Ktor HTTP client core library providing asynchronous HTTP client capabilities for Kotlin multiplatform applications
npx @tessl/cli install tessl/maven-io-ktor--ktor-client-core-jvm@2.3.0Ktor HTTP Client Core is a powerful, asynchronous HTTP client library for Kotlin multiplatform applications. It provides comprehensive HTTP client capabilities including request/response handling, client configuration, content negotiation, and an extensible plugin system. The library supports multiple platforms (JVM, JavaScript, Native) with a coroutine-based API for non-blocking HTTP operations.
implementation("io.ktor:ktor-client-core:2.3.13") to your build.gradle.ktsimport io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.plugins.*For engine-specific implementations:
import io.ktor.client.engine.cio.* // CIO engine
import io.ktor.client.engine.apache.* // Apache engineimport io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
// Create a client
val client = HttpClient()
// Make a simple GET request
val response: HttpResponse = client.get("https://api.example.com/users")
val body: String = response.bodyAsText()
// Make a POST request with JSON
val postResponse = client.post("https://api.example.com/users") {
header("Content-Type", "application/json")
setBody("""{"name": "John", "email": "john@example.com"}""")
}
// Close the client when done
client.close()Ktor HTTP Client is built around several key components:
Core client setup and configuration including engine selection, connection settings, and basic client lifecycle management.
class HttpClient(
engine: HttpClientEngine = HttpClientEngineContainer.default,
block: HttpClientConfig<*>.() -> Unit = {}
) : Closeable
fun HttpClient(
block: HttpClientConfig<*>.() -> Unit = {}
): HttpClient
class HttpClientConfig<T : HttpClientEngineConfig>(
val engine: HttpClientEngineFactory<T>
)Comprehensive request building capabilities including HTTP methods, headers, parameters, and body content with type-safe DSL.
class HttpRequestBuilder {
var method: HttpMethod
val url: URLBuilder
val headers: HeadersBuilder
var body: OutgoingContent
}
suspend fun HttpClient.get(urlString: String): HttpResponse
suspend fun HttpClient.post(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponseComplete response processing including content reading, status handling, and type-safe response body parsing.
abstract class HttpResponse : HttpMessage, CoroutineScope {
abstract val status: HttpStatusCode
abstract val version: HttpProtocolVersion
abstract val requestTime: GMTDate
abstract val responseTime: GMTDate
abstract val call: HttpClientCall
}
suspend fun HttpResponse.bodyAsText(charset: Charset = Charsets.UTF_8): String
suspend fun HttpResponse.bodyAsBytes(): ByteArray
suspend fun HttpResponse.bodyAsChannel(): ByteReadChannelRequest-response pair management with call lifecycle and typed body receiving capabilities.
class HttpClientCall(
val client: HttpClient,
val request: HttpRequest,
val response: HttpResponse
) : CoroutineScope {
val attributes: Attributes
suspend fun <T> body(): T
suspend fun body(info: TypeInfo): Any
suspend fun bodyNullable(info: TypeInfo): Any?
}
// Extension functions for response body handling
suspend fun <T> HttpResponse.body(): T
suspend fun <T> HttpResponse.body(typeInfo: TypeInfo): TExtensible plugin architecture for adding cross-cutting concerns like authentication, logging, caching, and content negotiation.
interface HttpClientPlugin<out TConfig : Any, TPlugin : Any> {
val key: AttributeKey<TPlugin>
fun prepare(block: TConfig.() -> Unit): TPlugin
fun install(plugin: TPlugin, scope: HttpClient)
}
fun <TConfig : Any, TPlugin : Any> createClientPlugin(
name: String,
createConfiguration: () -> TConfig,
body: ClientPluginBuilder<TConfig>.() -> TPlugin
): HttpClientPlugin<TConfig, TPlugin>Full WebSocket client implementation with session management, message handling, and connection lifecycle.
object WebSockets : HttpClientPlugin<WebSockets.Config, WebSockets>
interface ClientWebSocketSession : WebSocketSession {
val call: HttpClientCall
}
suspend fun HttpClient.webSocket(
urlString: String,
block: suspend ClientWebSocketSession.() -> Unit
)Prepared statement functionality for reusable HTTP requests with lazy execution and type-safe response handling.
class HttpStatement(
val builder: HttpRequestBuilder,
val client: HttpClient
) {
suspend fun execute(): HttpResponse
suspend fun <T> execute(block: suspend (HttpResponse) -> T): T
suspend fun <T> body(): T
suspend fun <T, R> body(block: suspend (T) -> R): R
}Advanced content processing including form data, multipart uploads, progress monitoring, and content transformation.
sealed class OutgoingContent {
class ByteArrayContent(val bytes: ByteArray) : OutgoingContent()
class ReadChannelContent(val readFrom: ByteReadChannel) : OutgoingContent()
class WriteChannelContent(
val body: suspend ByteWriteChannel.() -> Unit
) : OutgoingContent()
}
class FormDataContent(val formData: Parameters) : OutgoingContent()
class MultiPartFormDataContent(val parts: List<PartData>) : OutgoingContent()Timeout configuration plugin for request, connection, and socket timeouts with per-request customization.
object HttpTimeout : HttpClientPlugin<HttpTimeoutCapabilityConfiguration, HttpTimeout> {
const val INFINITE_TIMEOUT_MS: Long
}
class HttpTimeoutCapabilityConfiguration {
var requestTimeoutMillis: Long?
var connectTimeoutMillis: Long?
var socketTimeoutMillis: Long?
}
// Extension function for request-specific timeout
fun HttpRequestBuilder.timeout(block: HttpTimeoutCapabilityConfiguration.() -> Unit)Client lifecycle events and monitoring hooks for observing request/response processing.
object ClientEvents {
val HttpRequestCreated: EventDefinition<HttpRequestBuilder>
val HttpRequestIsReadyForSending: EventDefinition<HttpRequestBuilder>
val HttpResponseReceived: EventDefinition<HttpResponse>
val HttpResponseReceiveFailed: EventDefinition<HttpResponseReceiveFail>
val HttpResponseCancelled: EventDefinition<HttpResponse>
}
data class HttpResponseReceiveFail(
val request: HttpRequest,
val cause: Throwable
)Client engine abstraction allowing different HTTP implementations with engine-specific configuration and capabilities.
interface HttpClientEngine : CoroutineScope, Closeable {
val config: HttpClientEngineConfig
val dispatcher: CoroutineDispatcher
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
suspend fun execute(data: HttpRequestData): HttpResponseData
}
interface HttpClientEngineFactory<T : HttpClientEngineConfig> {
fun create(block: T.() -> Unit = {}): HttpClientEngine
}// Core client types
interface HttpRequest : HttpMessage, CoroutineScope {
val call: HttpClientCall
val method: HttpMethod
val url: Url
val attributes: Attributes
val content: OutgoingContent
}
data class HttpRequestData(
val url: Url,
val method: HttpMethod,
val headers: Headers,
val body: OutgoingContent,
val executionContext: Job,
val attributes: Attributes
) {
fun <T> getCapabilityOrNull(key: HttpClientEngineCapability<T>): T?
}
data class HttpResponseData(
val statusCode: HttpStatusCode,
val requestTime: GMTDate,
val headers: Headers,
val version: HttpProtocolVersion,
val body: Any,
val callContext: CoroutineContext
) {
val responseTime: GMTDate
}
// Configuration types
open class HttpClientEngineConfig {
var threadsCount: Int = 4
var pipelining: Boolean = false
var proxy: ProxyConfig? = null
}
// Base interfaces
interface HttpMessage {
val headers: Headers
val call: HttpClientCall
}
interface HttpClientEngineCapability<T>
// Plugin types
class AttributeKey<T>(val name: String)
data class Attributes(private val map: ConcurrentMap<AttributeKey<*>, Any>) {
fun <T> get(key: AttributeKey<T>): T
fun <T> getOrNull(key: AttributeKey<T>): T?
fun <T> put(key: AttributeKey<T>, value: T)
fun <T> remove(key: AttributeKey<T>): T?
fun <T> computeIfAbsent(key: AttributeKey<T>, block: () -> T): T
operator fun <T> contains(key: AttributeKey<T>): Boolean
}
// Exception types
class DoubleReceiveException(call: HttpClientCall) : IllegalStateException()
class NoTransformationFoundException(from: TypeInfo, to: TypeInfo) : UnsupportedOperationException()
class ReceivePipelineException(
request: HttpRequest,
info: TypeInfo,
cause: Throwable
) : IllegalStateException()
// Timeout exception types
class HttpRequestTimeoutException(
request: HttpRequestBuilder,
timeoutMillis: Long
) : IOException()
class ConnectTimeoutException(
request: HttpRequestData,
timeoutMillis: Long
) : IOException()
class SocketTimeoutException(
request: HttpRequestData
) : IOException()