CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-core-jvm

Ktor HTTP client core library providing asynchronous HTTP client capabilities for Kotlin multiplatform applications

Pending
Overview
Eval results
Files

request-building.mddocs/

Request Building

Comprehensive HTTP request building capabilities including HTTP methods, headers, parameters, body content, and type-safe DSL for constructing HTTP requests.

Capabilities

HTTP Request Builder

Core request building functionality with DSL support.

/**
 * Builder for constructing HTTP requests
 */
class HttpRequestBuilder {
    /** HTTP method (GET, POST, etc.) */
    var method: HttpMethod = HttpMethod.Get
    
    /** URL builder for constructing request URLs */
    val url: URLBuilder = URLBuilder()
    
    /** Headers builder for request headers */
    val headers: HeadersBuilder = HeadersBuilder()
    
    /** Request body content */
    var body: Any = EmptyContent
    
    /** Body type information for serialization */
    var bodyType: TypeInfo? = null
    
    /** Request execution context */
    var executionContext: Job = Job()
    
    /** Request attributes */
    val attributes: Attributes = Attributes()
    
    /** Build immutable request data */
    fun build(): HttpRequestData
    
    /** Copy from another builder */
    fun takeFrom(builder: HttpRequestBuilder): HttpRequestBuilder
    
    /** Copy from another builder with execution context */
    fun takeFromWithExecutionContext(builder: HttpRequestBuilder): HttpRequestBuilder
    
    /** Set engine capability */
    fun <T> setCapability(key: HttpClientEngineCapability<T>, capability: T)
    
    /** Get engine capability */
    fun <T> getCapabilityOrNull(key: HttpClientEngineCapability<T>): T?
}

/**
 * Build an HTTP request using DSL
 * @param block - Request configuration block
 */
suspend fun HttpClient.request(
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

suspend fun HttpClient.request(
    url: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

Usage Examples:

import io.ktor.client.request.*
import io.ktor.http.*

val client = HttpClient()

// Basic request with DSL
val response = client.request {
    method = HttpMethod.Post
    url("https://api.example.com/users")
    header("Authorization", "Bearer token123")
    header("Content-Type", "application/json")
    setBody("""{"name": "John", "email": "john@example.com"}""")
}

// Request with URL and configuration
val getResponse = client.request("https://api.example.com/users") {
    method = HttpMethod.Get
    parameter("page", 1)
    parameter("limit", 10)
}

HTTP Method Extensions

Convenient extension functions for common HTTP methods.

/**
 * Perform GET request
 */
suspend fun HttpClient.get(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

suspend fun HttpClient.get(
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform POST request
 */
suspend fun HttpClient.post(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

suspend fun HttpClient.post(
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform PUT request
 */
suspend fun HttpClient.put(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform DELETE request
 */
suspend fun HttpClient.delete(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform PATCH request
 */
suspend fun HttpClient.patch(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform HEAD request
 */
suspend fun HttpClient.head(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Perform OPTIONS request
 */
suspend fun HttpClient.options(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

Usage Examples:

val client = HttpClient()

// Simple GET request
val users = client.get("https://api.example.com/users")

// POST with body
val newUser = client.post("https://api.example.com/users") {
    contentType(ContentType.Application.Json)
    setBody("""{"name": "Alice", "email": "alice@example.com"}""")
}

// PUT with parameters
val updatedUser = client.put("https://api.example.com/users/123") {
    parameter("force", true)
    setBody(userJson)
}

// DELETE request
val deleteResponse = client.delete("https://api.example.com/users/123")

URL Building

Build and manipulate URLs with parameters and path segments.

/**
 * URL builder for constructing request URLs
 */
class URLBuilder {
    /** Protocol (http, https) */
    var protocol: URLProtocol = URLProtocol.HTTP
    
    /** Host name */
    var host: String = "localhost"
    
    /** Port number */
    var port: Int = DEFAULT_PORT
    
    /** Path segments */
    val pathSegments: MutableList<String>
    
    /** Query parameters */
    val parameters: ParametersBuilder
    
    /** URL fragment */
    var fragment: String = ""
}

/**
 * Set request URL
 */
fun HttpRequestBuilder.url(urlString: String)
fun HttpRequestBuilder.url(url: Url)
fun HttpRequestBuilder.url(block: URLBuilder.() -> Unit)

Usage Examples:

client.get {
    url {
        protocol = URLProtocol.HTTPS
        host = "api.example.com"
        port = 443
        path("v1", "users", "123")
        parameter("include", "profile")
        parameter("fields", "name,email")
        fragment = "section1"
    }
}

// Or using string URL
client.get("https://api.example.com/v1/users/123?include=profile&fields=name,email#section1")

Header Management

Add and manage HTTP headers.

/**
 * Set request header
 */
fun HttpRequestBuilder.header(key: String, value: String)
fun HttpRequestBuilder.header(key: String, value: Number)
fun HttpRequestBuilder.header(key: String, value: Boolean)

/**
 * Append header value (for headers that support multiple values)
 */
fun HttpRequestBuilder.append(key: String, value: String)

/**
 * Set content type header
 */
fun HttpRequestBuilder.contentType(contentType: ContentType)

/**
 * Set accept header
 */
fun HttpRequestBuilder.accept(contentType: ContentType)

/**
 * Set authorization header
 */
fun HttpRequestBuilder.bearerAuth(token: String)
fun HttpRequestBuilder.basicAuth(username: String, password: String)

Usage Examples:

client.post("https://api.example.com/users") {
    // Standard headers
    header("User-Agent", "MyApp/1.0")
    header("X-Request-ID", UUID.randomUUID().toString())
    
    // Content type
    contentType(ContentType.Application.Json)
    
    // Accept header
    accept(ContentType.Application.Json)
    
    // Authentication
    bearerAuth("your-jwt-token")
    
    // Multiple values for same header
    append("Accept-Encoding", "gzip")
    append("Accept-Encoding", "deflate")
}

Parameter Management

Add URL parameters and form parameters.

/**
 * Add URL parameter
 */
fun HttpRequestBuilder.parameter(key: String, value: Any?)

/**
 * Set multiple parameters from map
 */
fun HttpRequestBuilder.parameters(block: ParametersBuilder.() -> Unit)

/**
 * Parameters builder for query string parameters
 */
class ParametersBuilder {
    fun append(name: String, value: String)
    fun appendAll(name: String, values: Iterable<String>)
    fun set(name: String, value: String)
    fun remove(name: String)
    fun clear()
}

Usage Examples:

client.get("https://api.example.com/search") {
    parameter("q", "kotlin")
    parameter("limit", 50)
    parameter("offset", 0)
    parameter("sort", "created_desc")
    
    // Multiple parameters at once
    parameters {
        append("filter", "published")
        append("filter", "featured")
        append("category", "programming")
    }
}

Request Body

Set request body content with various content types.

/**
 * Set request body with type safety
 */
inline fun <reified T> HttpRequestBuilder.setBody(body: T)

/**
 * Set request body with type information
 */
fun HttpRequestBuilder.setBody(body: Any, bodyType: TypeInfo)

/**
 * Set request body (generic)
 */
fun HttpRequestBuilder.setBody(body: Any)

/**
 * Set request body with specific content type
 */
fun HttpRequestBuilder.setBody(
    body: Any,
    contentType: ContentType? = null
)

/**
 * Base class for outgoing content
 */
sealed class OutgoingContent {
    /** Content from byte array */
    class ByteArrayContent(val bytes: ByteArray) : OutgoingContent()
    
    /** Content from string */
    class TextContent(
        val text: String,
        val contentType: ContentType
    ) : OutgoingContent()
    
    /** Content from read channel */
    class ReadChannelContent(
        val readFrom: ByteReadChannel
    ) : OutgoingContent()
    
    /** Content for write channel */
    class WriteChannelContent(
        val body: suspend ByteWriteChannel.() -> Unit
    ) : OutgoingContent()
    
    /** Empty content */
    object NoContent : OutgoingContent()
}

Usage Examples:

// String body
client.post("https://api.example.com/users") {
    contentType(ContentType.Application.Json)
    setBody("""{"name": "John", "email": "john@example.com"}""")
}

// Byte array body
client.post("https://api.example.com/upload") {
    contentType(ContentType.Application.OctetStream)
    setBody(fileBytes)
}

// Object body (requires content negotiation plugin)
data class User(val name: String, val email: String)
client.post("https://api.example.com/users") {
    contentType(ContentType.Application.Json)
    setBody(User("John", "john@example.com"))
}

// Channel content
client.post("https://api.example.com/stream") {
    setBody(ChannelWriterContent { channel ->
        channel.writeStringUtf8("Hello ")
        channel.writeStringUtf8("World!")
        channel.close()
    })
}

Request Utilities

Utility functions for common request operations.

/**
 * Set timeout for specific request
 */
fun HttpRequestBuilder.timeout(block: HttpTimeoutConfig.() -> Unit)

/**
 * Add request attributes
 */
fun HttpRequestBuilder.attributes(block: Attributes.() -> Unit)

/**
 * Set request tag for identification
 */
fun HttpRequestBuilder.tag(tag: Any)

Usage Examples:

client.get("https://api.example.com/slow-endpoint") {
    // Set specific timeout for this request
    timeout {
        requestTimeoutMillis = 30000
        connectTimeoutMillis = 5000
    }
    
    // Add custom attributes
    attributes {
        put(customAttributeKey, customValue)
    }
    
    // Tag request for identification
    tag("slow-request")
}

Types

// Request types
data class HttpRequestData(
    val url: Url,
    val method: HttpMethod,
    val headers: Headers,
    val body: OutgoingContent,
    val executionContext: Job,
    val attributes: Attributes
)

interface HttpRequest : HttpMessage {
    val call: HttpClientCall
    val method: HttpMethod
    val url: Url
}

// URL types
enum class URLProtocol {
    HTTP, HTTPS, WS, WSS, SOCKS
}

// Content types
class ContentType private constructor(
    val contentType: String,
    val contentSubtype: String,
    val parameters: List<HeaderValueParam> = emptyList()
) {
    companion object {
        object Application {
            val Json = ContentType("application", "json")
            val Xml = ContentType("application", "xml")
            val OctetStream = ContentType("application", "octet-stream")
            val FormUrlEncoded = ContentType("application", "x-www-form-urlencoded")
        }
        
        object Text {
            val Plain = ContentType("text", "plain")
            val Html = ContentType("text", "html")
            val CSS = ContentType("text", "css")
        }
    }
}

// HTTP methods
class HttpMethod(val value: String) {
    companion object {
        val Get = HttpMethod("GET")
        val Post = HttpMethod("POST")
        val Put = HttpMethod("PUT")
        val Delete = HttpMethod("DELETE")
        val Patch = HttpMethod("PATCH")
        val Head = HttpMethod("HEAD")
        val Options = HttpMethod("OPTIONS")
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-core-jvm

docs

client-configuration.md

content-handling.md

engine-architecture.md

events-monitoring.md

http-statement.md

index.md

plugin-system.md

request-building.md

response-handling.md

websocket-support.md

tile.json