diff --git a/codeSnippets/snippets/client-configure-request/src/main/kotlin/com/example/Application.kt b/codeSnippets/snippets/client-configure-request/src/main/kotlin/com/example/Application.kt index a0c19ccf2..0a339b366 100644 --- a/codeSnippets/snippets/client-configure-request/src/main/kotlin/com/example/Application.kt +++ b/codeSnippets/snippets/client-configure-request/src/main/kotlin/com/example/Application.kt @@ -6,6 +6,7 @@ import io.ktor.client.plugins.logging.* import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* +import io.ktor.util.appendAll import io.ktor.util.date.* import kotlinx.coroutines.* @@ -51,6 +52,24 @@ fun main() { } } + // Add multiple headers + client.get("https://ktor.io") { + headers { + // Using vararg Pairs + appendAll( + HttpHeaders.Accept to "text/html", + HttpHeaders.Authorization to "abc123" + ) + + // Using a Map + appendAll(mapOf("foo" to "bar", "baz" to "qux")) + appendAll(mapOf("test" to listOf("1", "2", "3"))) + + // Using a custom header with multiple values + appendAll("X-Custom-Header" to listOf("val1", "val2")) + } + } + // Add cookies client.get("https://ktor.io") { cookie(name = "user_name", value = "jetbrains", expires = GMTDate( diff --git a/topics/client-requests.md b/topics/client-requests.md index 8a5e84709..68cd77fb1 100644 --- a/topics/client-requests.md +++ b/topics/client-requests.md @@ -72,7 +72,7 @@ The example above can be simplified using the `.get()` function: ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="21"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="22"} In both examples, a request URL is specified as a string. You can also configure URL components separately using [`HttpRequestBuilder`](#url). @@ -86,14 +86,14 @@ The Ktor client allows you to configure a request URL in multiple ways: ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="21"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="22"} ### Configure URL components separately ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="22-28"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="23-29"} In this case, the `url` parameter provided by `HttpRequestBuilder` is used. It accepts an instance of [`URLBuilder`](https://api.ktor.io/ktor-http/io.ktor.http/-u-r-l-builder/index.html), offering more flexibility for @@ -109,7 +109,7 @@ Alternatively, you can pass individual path segments using the `appendPathSegmen ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="29-33"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="30-34"} By default, `appendPathSegments` [encodes][percent_encoding] path segments. To disable encoding, use `appendEncodedPathSegments()` instead. @@ -121,7 +121,7 @@ To add query string parameters, use ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="34-38"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="35-39"} By default, `parameters` [encodes][percent_encoding] query parameters. To disable encoding, use `encodedParameters()` instead. @@ -136,7 +136,7 @@ You can configure a URL fragment using the `fragment` property. ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="39-43"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="40-44"} By default, `fragment` [encodes][percent_encoding] a URL fragment. To disable encoding, use `encodedFragment()` instead. @@ -179,7 +179,14 @@ you to add several headers at once: ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="46-52"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="47-53"} + +You can also use the `appendAll()` function with a `Map` or `vararg Pair` to add multiple headers conveniently: + +```kotlin +``` + +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="56-71"} #### Add a single header @@ -200,7 +207,7 @@ To send cookies, use the ```kotlin ``` -{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="55-64"} +{src="snippets/client-configure-request/src/main/kotlin/com/example/Application.kt" include-lines="74-83"} Ktor also provides the [`HttpCookies`](client-cookies.md) plugin that allows you to keep cookies between calls. If this plugin is installed, cookies added using the `cookie()` function are ignored. diff --git a/topics/server-responses.md b/topics/server-responses.md index df4cb2ad9..63296a374 100644 --- a/topics/server-responses.md +++ b/topics/server-responses.md @@ -116,9 +116,12 @@ get("/") { There are several ways to send specific headers in a response: * Add a header to the [ApplicationResponse.headers](https://api.ktor.io/ktor-server-core/io.ktor.server.response/-application-response/headers.html) collection: ```kotlin - get("/") { - call.response.headers.append(HttpHeaders.ETag, "7c876b7e") - } + get("/") { + call.response.headers.append(HttpHeaders.ETag, "7c876b7e") + + // For multiple values for the same header + call.response.headers.appendAll("X-Custom-Header" to listOf("value1", "value2")) + } ``` * Call the [ApplicationResponse.header](https://api.ktor.io/ktor-server-core/io.ktor.server.response/header.html) function: diff --git a/topics/whats-new-320.md b/topics/whats-new-320.md index ba6d01bdd..41cf1cc32 100644 --- a/topics/whats-new-320.md +++ b/topics/whats-new-320.md @@ -410,7 +410,7 @@ Ktor’s HTMX support is available across three experimental modules: All APIs are marked with `@ExperimentalKtorApi` and require opt-in via `@OptIn(ExperimentalKtorApi::class)`. For more information, see [](htmx-integration.md). -## Unix domain sockets +### Unix domain sockets With 3.2.0, you can set up Ktor clients to connect to Unix domain sockets and Ktor servers to listen to such sockets. Currently, Unix domain sockets are only supported in the CIO engine. @@ -441,6 +441,26 @@ val response: HttpResponse = client.get("/") { You can also use a Unix domain socket in a [default request](client-default-request.md#unix-domain-sockets). +### New `.appendAll()` overloads for building headers and parameters + +The [`StringValuesBuilder.appendAll()`](https://api.ktor.io/ktor-utils/io.ktor.util/append-all.html) function has new +overloads that accept a `Map` or `vararg Pair`. This allows you to append multiple values in a single call, simplifying +the construction of headers, URL parameters, and other `StringValues`-based collections. + +The following example shows how to use these new overloads: + +```kotlin +val headers = buildHeaders { + // Using Map + appendAll(mapOf("foo" to "bar", "baz" to "qux")) + appendAll(mapOf("test" to listOf("1", "2", "3"))) + + // Using vararg Pair + appendAll("foo" to "bar", "baz" to "qux") + appendAll("test" to listOf("1", "2", "3")) +} +``` + ## Infrastructure ### Published version catalog