Multiplatform asynchronous HTTP client core library for JVM that provides request/response handling, plugin architecture, and extensible HTTP communication capabilities.
pkg:gradle/io.ktor/ktor-client-core-jvm@3.2.x
npx @tessl/cli install tessl/gradle-io-ktor--ktor-client-core-jvm@3.2.0Ktor Client Core JVM is a multiplatform asynchronous HTTP client library that provides comprehensive request/response handling, plugin architecture, and extensible HTTP communication capabilities. Built on Kotlin coroutines for non-blocking I/O operations, it offers high-performance HTTP communication with support for various authentication mechanisms, content negotiation, WebSocket connections, and Server-Sent Events.
dependencies {
implementation("io.ktor:ktor-client-core-jvm:3.2.0")
}import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.plugins.*For engine-specific usage:
import io.ktor.client.engine.apache.* // Apache engine
import io.ktor.client.engine.okhttp.* // OkHttp engineimport io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
// Create client
val client = HttpClient()
// Make GET request
val response: HttpResponse = client.get("https://api.example.com/users")
val body = response.bodyAsText()
// Make POST request with JSON
val postResponse = client.post("https://api.example.com/users") {
contentType(ContentType.Application.Json)
setBody("""{"name": "John", "email": "john@example.com"}""")
}
// Close client when done
client.close()Ktor Client Core is built around several key architectural components:
Main HTTP client functionality for creating clients, making requests, and handling responses. Provides the foundation for all HTTP operations.
class HttpClient(
engine: HttpClientEngine,
userConfig: HttpClientConfig<out HttpClientEngineConfig> = HttpClientConfig()
) : CoroutineScope, Closeable {
val engine: HttpClientEngine
val requestPipeline: HttpRequestPipeline
val responsePipeline: HttpResponsePipeline
val attributes: Attributes
val monitor: Events
fun close()
fun config(block: HttpClientConfig<*>.() -> Unit): HttpClient
fun isSupported(capability: HttpClientEngineCapability<*>): Boolean
}
expect fun HttpClient(block: HttpClientConfig<*>.() -> Unit = {}): HttpClient
fun <T : HttpClientEngineConfig> HttpClient(
engineFactory: HttpClientEngineFactory<T>,
block: HttpClientConfig<T>.() -> Unit = {}
): HttpClient
fun HttpClient(
engine: HttpClientEngine,
block: HttpClientConfig<*>.() -> Unit
): HttpClientComprehensive request building DSL with support for all HTTP methods, headers, query parameters, and body content.
suspend fun HttpClient.request(
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse
suspend fun HttpClient.get(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse
suspend fun HttpClient.post(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse
class HttpRequestBuilder {
var method: HttpMethod
val url: URLBuilder
val headers: HeadersBuilder
var body: Any
val attributes: Attributes
fun build(): HttpRequestData
fun url(block: URLBuilder.() -> Unit)
fun setBody(body: Any)
}Response handling with multiple content types, streaming support, and type-safe body extraction.
abstract class HttpResponse {
abstract val call: HttpClientCall
abstract val status: HttpStatusCode
abstract val version: HttpProtocolVersion
abstract val requestTime: GMTDate
abstract val responseTime: GMTDate
abstract val headers: Headers
}
suspend fun HttpResponse.bodyAsText(
fallbackCharset: Charset = Charsets.UTF_8
): String
suspend fun HttpResponse.bodyAsBytes(): ByteArray
fun HttpResponse.bodyAsChannel(): ByteReadChannel
suspend inline fun <reified T> HttpResponse.body(): T
class HttpStatement(
private val builder: HttpRequestBuilder,
private val client: HttpClient
) {
suspend fun <T> execute(
block: suspend (response: HttpResponse) -> T
): T
suspend fun execute(): HttpResponse
suspend inline fun <reified T> body(): T
}Extensible plugin architecture for adding functionality like authentication, caching, logging, and custom interceptors.
interface HttpClientPlugin<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> HttpClient.install(
plugin: HttpClientPlugin<TConfig, TPlugin>,
configure: TConfig.() -> Unit = {}
): TPlugin
fun <TConfig : Any, TPlugin : Any> HttpClient.plugin(
plugin: HttpClientPlugin<TConfig, TPlugin>
): TPluginHTTP engine abstraction and configuration for different backend implementations like Apache HttpClient, OkHttp, and CIO.
interface HttpClientEngine : CoroutineScope, Closeable {
val dispatcher: CoroutineDispatcher
val config: HttpClientEngineConfig
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
suspend fun execute(data: HttpRequestData): HttpResponseData
fun install(client: HttpClient)
}
interface HttpClientEngineFactory<out T : HttpClientEngineConfig> {
fun create(block: T.() -> Unit = {}): HttpClientEngine
}
abstract class HttpClientEngineConfig {
var dispatcher: CoroutineDispatcher?
var pipelining: Boolean
var proxy: ProxyConfig?
var threadsCount: Int
}Content serialization, form data, file uploads, and multipart support with type-safe handling.
class FormDataContent(val formData: Parameters) : OutgoingContent
class MultiPartFormDataContent(
parts: List<PartData>,
boundary: String = generateBoundary(),
contentType: ContentType = ContentType.MultiPart.FormData.withParameter("boundary", boundary)
) : OutgoingContent
class LocalFileContent(
val file: File,
override val contentType: ContentType = ContentType.defaultForFile(file)
) : OutgoingContent.ReadChannelContent()
suspend fun HttpClient.submitForm(
url: String,
formParameters: Parameters,
encodeInQuery: Boolean = false,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse
suspend fun HttpClient.submitFormWithBinaryData(
url: String,
formData: List<PartData>,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponseWebSocket client functionality with session management, frame handling, and connection lifecycle.
suspend fun <T> HttpClient.webSocket(
method: HttpMethod = HttpMethod.Get,
host: String = "localhost",
port: Int = DEFAULT_PORT,
path: String = "/",
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> T
): T
interface DefaultClientWebSocketSession : ClientWebSocketSession {
suspend fun send(frame: Frame)
suspend fun send(content: String)
suspend fun send(content: ByteArray)
val incoming: ReceiveChannel<Frame>
val outgoing: SendChannel<Frame>
}Server-Sent Events (SSE) client implementation for receiving real-time event streams from servers.
suspend fun <T> HttpClient.sse(
request: HttpRequestBuilder.() -> Unit = {},
reconnectionTime: Duration? = null,
showCommentEvents: Boolean = false,
showRetryEvents: Boolean = false,
block: suspend ClientSSESession.() -> T
): T
interface ClientSSESession {
val incoming: ReceiveChannel<ServerSentEvent>
}
data class ServerSentEvent(
val data: String?,
val event: String?,
val id: String?,
val retry: Int?,
val comments: String?
)class HttpClientCall(
val client: HttpClient
) {
val request: HttpRequest
val response: HttpResponse
val attributes: Attributes
suspend inline fun <reified T> body(): T
}
interface HttpRequest {
val call: HttpClientCall
val method: HttpMethod
val url: Url
val attributes: Attributes
val headers: Headers
val content: OutgoingContent
}
data class HttpRequestData(
val url: Url,
val method: HttpMethod,
val headers: Headers,
val body: OutgoingContent,
val executionContext: Job,
val attributes: Attributes
)
data class HttpResponseData(
val statusCode: HttpStatusCode,
val requestTime: GMTDate,
val headers: Headers,
val version: HttpProtocolVersion,
val body: Any,
val callContext: CoroutineContext,
val responseTime: GMTDate
)
class Attributes(concurrent: Boolean = false) {
fun <T : Any> put(key: AttributeKey<T>, value: T)
fun <T : Any> get(key: AttributeKey<T>): T
fun <T : Any> getOrNull(key: AttributeKey<T>): T?
fun <T : Any> take(key: AttributeKey<T>): T
fun <T : Any> takeOrNull(key: AttributeKey<T>): T?
fun <T : Any> contains(key: AttributeKey<T>): Boolean
fun <T : Any> remove(key: AttributeKey<T>)
}
data class AttributeKey<T>(val name: String)
interface TypeInfo {
val type: KType
val reifiedType: KClass<*>
val kotlinType: KType?
}