Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ import kotlin.coroutines.CoroutineContext
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public expect fun HttpClient(
block: HttpClientConfig<*>.() -> Unit = {}
): HttpClient
Expand Down Expand Up @@ -642,7 +641,6 @@ public expect fun HttpClient(
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public fun <T : HttpClientEngineConfig> HttpClient(
engineFactory: HttpClientEngineFactory<T>,
block: HttpClientConfig<T>.() -> Unit = {}
Expand Down Expand Up @@ -968,7 +966,6 @@ public fun <T : HttpClientEngineConfig> HttpClient(
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public fun HttpClient(
engine: HttpClientEngine,
block: HttpClientConfig<*>.() -> Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import io.ktor.utils.io.*
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public actual fun HttpClient(
block: HttpClientConfig<*>.() -> Unit
): HttpClient = HttpClient(FACTORY, block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import java.util.*
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public actual fun HttpClient(
block: HttpClientConfig<*>.() -> Unit
): HttpClient = HttpClient(FACTORY, block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import io.ktor.utils.io.*
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient)
*/
@KtorDsl
public actual fun HttpClient(
block: HttpClientConfig<*>.() -> Unit
): HttpClient = HttpClient(FACTORY, block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import io.ktor.utils.io.core.*
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.basic)
*/
@KtorDsl
public fun AuthConfig.basic(block: BasicAuthConfig.() -> Unit) {
with(BasicAuthConfig().apply(block)) {
[email protected](BasicAuthProvider(credentials, realm, _sendWithoutRequest))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import io.ktor.server.plugins.callid.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import kotlin.coroutines.*
import kotlin.test.*
import kotlinx.coroutines.currentCoroutineContext
import kotlin.test.Test
import kotlin.test.assertEquals
import io.ktor.server.plugins.callid.CallId as ServerCallId

class CallIdTest {
Expand All @@ -37,7 +38,7 @@ class CallIdTest {
}

val response = client.get("/1").bodyAsText()
assertEquals(response, "call-id-1:call-id-1:call-id-1")
assertEquals("call-id-1:call-id-1:call-id-1", response)
}

@Test
Expand All @@ -63,7 +64,7 @@ class CallIdTest {
}

val response = client.get("/1").bodyAsText()
assertEquals(response, "call-id-client-0:call-id-client-0:call-id-client-0")
assertEquals("call-id-client-0:call-id-client-0:call-id-client-0", response)
}

@Test
Expand All @@ -90,7 +91,7 @@ class CallIdTest {
}

val response = client.get("/1").bodyAsText()
assertEquals(response, "call-id-client-1:call-id-client-1:call-id-client-1")
assertEquals("call-id-client-1:call-id-client-1:call-id-client-1", response)
}

@Test
Expand All @@ -116,12 +117,13 @@ class CallIdTest {
}

val response = client.get("/1").bodyAsText()
assertEquals(response, "null:call-id-1")
assertEquals("null:call-id-1", response)
}

private suspend fun RoutingContext.respondWithCallId() {
val callIdFromCall = call.callId ?: error("No call id in call")
val callIdFromContext = coroutineContext[KtorCallIdContextElement]?.callId ?: error("No call id in context")
val callIdFromContext = currentCoroutineContext()[KtorCallIdContextElement]?.callId
?: error("No call id in context")
val callIdFromHeader = call.request.headers[HttpHeaders.XRequestId] ?: error("No call id in header")
call.respond("$callIdFromCall:$callIdFromContext:$callIdFromHeader")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public fun interface WebRtcClientEngineFactory<out T : WebRtcConfig> {
* ```
* @param block configuration block for the client
*/
@KtorDsl
@ExperimentalKtorApi
public fun <T : WebRtcConfig> WebRtcClient(
factory: WebRtcClientEngineFactory<T>,
Expand Down
2 changes: 1 addition & 1 deletion ktor-io/common/src/io/ktor/utils/io/Annotations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,5 @@ public annotation class PublicAPICandidate(val version: String)
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.KtorDsl)
*/
@DslMarker
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE, AnnotationTarget.FUNCTION)
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE)
public annotation class KtorDsl
Comment on lines +111 to 112
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Removal of FUNCTION from KtorDsl target — good; please verify no lingering usages and call out the breaking change.

This aligns with the PR intent to move DSL scoping to receiver types; it will surface compile errors for any remaining function-annotated sites.

Run this to ensure no functions are still annotated with @KtorDsl:

Also add a release note entry explicitly stating the target list change for @KtorDsl (FUNCTION dropped) and the migration path (annotate receiver types instead).


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Same-line annotation on functions
rg -nP --type=kt --type=kts '@KtorDsl\s+.*\bfun\b' -g '!**/build/**' || true

# Multiline: annotation on a line above the function (handles stacked annotations/modifiers)
rg -nPU --type=kt --type=kts '(?s)@KtorDsl\s*(?:\n\s*@\w[^\n]*)*\s*(?:public|private|internal|protected)?\s*(?:suspend\s+)?fun\b' -g '!**/build/**' || true

Length of output: 308


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for @KtorDsl on the same line as fun in all Kotlin files
rg -nP '@KtorDsl.*\bfun\b' -g '*.kt' -g '*.kts' -g '!**/build/**' || true

# Search for @KtorDsl annotation on a line above function declarations (handles stacked annotations)
rg -nPU '(?s)@KtorDsl\s*(?:\n\s*@\w[^\n]*)*\s*(?:public|private|internal|protected)?\s*(?:suspend\s+)?fun\b' -g '*.kt' -g '*.kts' -g '!**/build/**' || true

Length of output: 2615


Remove @KtorDsl annotations from functions in DI plugin and test-host modules

  • DI plugin overloads (common/src/io/ktor/server/plugins/di/DependencyProviderLambdaOverloads.kt lines 20, 36, 51, 67, 84, 102, 121)
  • TestApplication APIs (common/src/io/ktor/server/testing/TestApplication.kt lines 58–59, 136–137, 163–164)

@KtorDsl no longer targets FUNCTION, so these sites will fail to compile. Remove the annotation from each function or migrate to annotating the receiver type instead. Don’t forget to add a release-note entry covering the dropped FUNCTION target and migration path.

🤖 Prompt for AI Agents
In ktor-io/common/src/io/ktor/utils/io/Annotations.kt around lines 111-112,
@KtorDsl no longer targets FUNCTION which breaks call sites: remove @KtorDsl
from all function declarations in the DI plugin overloads
(common/src/io/ktor/server/plugins/di/DependencyProviderLambdaOverloads.kt lines
~20, 36, 51, 67, 84, 102, 121) and TestApplication APIs
(common/src/io/ktor/server/testing/TestApplication.kt lines ~58–59, 136–137,
163–164); alternatively, if DSL scoping is needed, move the annotation to the
receiver type (annotate the receiver class/type instead of the functions);
update or add a release-note entry describing the dropped FUNCTION target and
the migration path (remove annotations from functions or annotate receiver
types).

1 change: 1 addition & 0 deletions ktor-server/ktor-server-core/api/ktor-server-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,7 @@ public class io/ktor/server/routing/RoutingNode : io/ktor/server/application/App

public final class io/ktor/server/routing/RoutingNodeKt {
public static final fun getAllRoutes (Lio/ktor/server/routing/RoutingNode;)Ljava/util/List;
public static final fun getApplication (Lio/ktor/server/routing/RoutingContext;)Lio/ktor/server/application/Application;
public static final fun getPath (Lio/ktor/server/routing/RoutingNode;)Ljava/lang/String;
public static final fun insertPhaseAfter (Lio/ktor/server/routing/Route;Lio/ktor/util/pipeline/PipelinePhase;Lio/ktor/util/pipeline/PipelinePhase;)V
public static final fun insertPhaseBefore (Lio/ktor/server/routing/Route;Lio/ktor/util/pipeline/PipelinePhase;Lio/ktor/util/pipeline/PipelinePhase;)V
Expand Down
2 changes: 2 additions & 0 deletions ktor-server/ktor-server-core/api/ktor-server-core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,8 @@ final val io.ktor.server.routing/RoutingFailureStatusCode // io.ktor.server.rout
final fun <get-RoutingFailureStatusCode>(): io.ktor.util/AttributeKey<io.ktor.http/HttpStatusCode> // io.ktor.server.routing/RoutingFailureStatusCode.<get-RoutingFailureStatusCode>|<get-RoutingFailureStatusCode>(){}[0]
final val io.ktor.server.routing/application // io.ktor.server.routing/application|@io.ktor.server.routing.Route{}application[0]
final fun (io.ktor.server.routing/Route).<get-application>(): io.ktor.server.application/Application // io.ktor.server.routing/application.<get-application>|<get-application>@io.ktor.server.routing.Route(){}[0]
final val io.ktor.server.routing/application // io.ktor.server.routing/application|@io.ktor.server.routing.RoutingContext{}application[0]
final fun (io.ktor.server.routing/RoutingContext).<get-application>(): io.ktor.server.application/Application // io.ktor.server.routing/application.<get-application>|<get-application>@io.ktor.server.routing.RoutingContext(){}[0]
final val io.ktor.server.routing/path // io.ktor.server.routing/path|@io.ktor.server.routing.RoutingNode{}path[0]
final fun (io.ktor.server.routing/RoutingNode).<get-path>(): kotlin/String // io.ktor.server.routing/path.<get-path>|<get-path>@io.ktor.server.routing.RoutingNode(){}[0]
final val io.ktor.server.routing/routingRoot // io.ktor.server.routing/routingRoot|@io.ktor.server.application.Application{}routingRoot[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import kotlin.coroutines.EmptyCoroutineContext
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfigBuilder)
*/
@KtorDsl
public class ServerConfigBuilder(
public val environment: ApplicationEnvironment
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ package io.ktor.server.engine

import io.ktor.server.application.*
import io.ktor.server.engine.internal.*
import kotlinx.coroutines.*
import io.ktor.utils.io.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
* An engine which runs an application.
Expand All @@ -21,6 +23,7 @@ public interface ApplicationEngine {
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration)
*/
@Suppress("MemberVisibilityCanBePrivate")
@KtorDsl
public open class Configuration {
/**
* Returns the current parallelism level (e.g. the number of available processors).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package io.ktor.server.engine

import io.ktor.utils.io.*

/**
* Represents a type of a connector, e.g HTTP or HTTPS.
*
Expand Down Expand Up @@ -80,6 +82,7 @@ public inline fun ApplicationEngine.Configuration.connector(builder: EngineConne
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorBuilder)
*/
@KtorDsl
public open class EngineConnectorBuilder(
override val type: ConnectorType = ConnectorType.HTTP
) : EngineConnectorConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.util.*
import io.ktor.utils.io.*
import kotlin.jvm.*
import kotlin.jvm.JvmName

/**
* Builds a route to match the specified regex [path].
Expand All @@ -27,7 +26,6 @@ import kotlin.jvm.*
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route)
*/
@KtorDsl
public fun Route.route(path: Regex, build: Route.() -> Unit): Route =
createRouteFromRegexPath(path).apply(build)

Expand All @@ -47,7 +45,6 @@ public fun Route.route(path: Regex, build: Route.() -> Unit): Route =
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route)
*/
@KtorDsl
public fun Route.route(path: Regex, method: HttpMethod, build: Route.() -> Unit): Route {
val selector = HttpMethodRouteSelector(method)
return createRouteFromRegexPath(path).createChild(selector).apply(build)
Expand All @@ -67,7 +64,6 @@ public fun Route.route(path: Regex, method: HttpMethod, build: Route.() -> Unit)
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.get)
*/
@KtorDsl
public fun Route.get(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Get) { handle(body) }
}
Expand All @@ -86,7 +82,6 @@ public fun Route.get(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post)
*/
@KtorDsl
public fun Route.post(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Post) { handle(body) }
}
Expand All @@ -105,7 +100,6 @@ public fun Route.post(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post)
*/
@KtorDsl
@JvmName("postTypedPath")
public inline fun <reified R : Any> Route.post(
path: Regex,
Expand All @@ -128,7 +122,6 @@ public inline fun <reified R : Any> Route.post(
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.head)
*/
@KtorDsl
public fun Route.head(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Head) { handle(body) }
}
Expand All @@ -147,7 +140,6 @@ public fun Route.head(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put)
*/
@KtorDsl
public fun Route.put(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Put) { handle(body) }
}
Expand All @@ -166,7 +158,6 @@ public fun Route.put(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put)
*/
@KtorDsl
@JvmName("putTypedPath")
public inline fun <reified R : Any> Route.put(
path: Regex,
Expand All @@ -189,7 +180,6 @@ public inline fun <reified R : Any> Route.put(
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch)
*/
@KtorDsl
public fun Route.patch(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Patch) { handle(body) }
}
Expand All @@ -208,7 +198,6 @@ public fun Route.patch(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch)
*/
@KtorDsl
@JvmName("patchTypedPath")
public inline fun <reified R : Any> Route.patch(
path: Regex,
Expand All @@ -231,7 +220,6 @@ public inline fun <reified R : Any> Route.patch(
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.delete)
*/
@KtorDsl
public fun Route.delete(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Delete) { handle(body) }
}
Expand All @@ -250,7 +238,6 @@ public fun Route.delete(path: Regex, body: RoutingHandler): Route {
*
* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.options)
*/
@KtorDsl
public fun Route.options(path: Regex, body: RoutingHandler): Route {
return route(path, HttpMethod.Options) { handle(body) }
}
Expand Down
Loading