Ktor 3.0.0 Help

CallId

The CallId plugin allows you to trace client requests end-to-end by using unique call IDs. It is particularly useful in microservice architectures to keep track of calls, regardless of how many services a request goes through.

A calling scope might already have a call ID in its coroutine context. By default, the plugin uses the current context to retrieve a call ID and adds it to the context of the specific call using the HttpHeaders.XRequestId header.

Additionally, if a scope comes without a call ID, you can configure the plugin to generate and apply a new call ID.

Add dependencies

To use CallId, you need to include the ktor-client-call-id artifact in the build script:

implementation("io.ktor:ktor-client-call-id:$ktor_version")
implementation "io.ktor:ktor-client-call-id:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-client-call-id-jvm</artifactId> <version>${ktor_version}</version> </dependency>

Install CallId

To install the CallId plugin to the application, pass it to the install function in the specified module. The code snippets below show how to install CallId...

  • ... inside the embeddedServer function call.

  • ... inside the explicitly defined module, which is an extension function of the Application class.

import io.ktor.server.application.* import io.ktor.client.plugins.callid.* // ... fun main() { embeddedServer(Netty, port = 8080) { install(CallId) // ... }.start(wait = true) }
import io.ktor.server.application.* import io.ktor.client.plugins.callid.* // ... fun Application.module() { install(CallId) // ... }

Configure CallId

The CallId plugin configuration, provided by the CallIdConfig class, allows you to generate a call ID and add it to the call context.

Generate a call ID

Generate a call ID for a specific request in one of the following ways:

  • The useCoroutineContext property, enabled by default, adds a generator that uses the current CoroutineContext to retrieve a call ID. To disable this functionality, set useCoroutineContext to false:

install(CallId) { useCoroutineContext = false }
  • The generate() function allows you to generate a call ID for an outgoing request. If it fails to generate a call ID, it returns null.

install(CallId) { generate { "call-id-client-2" } }

You can use multiple methods to generate a call ID. In this way, the first non-null value will be applied.

Add a call ID

After you retrieve a call ID, you have the following options available to add it to the request:

  • The intercept() function allows you to add a call ID to the request by using the CallIdInterceptor.

install(ClientCallId) { intercept { request, callId -> request.header(HttpHeaders.XRequestId, callId) } }
  • The addToHeader() function adds a call ID to a specified header. It takes a header as a parameter, which defaults to HttpHeaders.XRequestId.

install(CallId) { addToHeader(HttpHeaders.XRequestId) }

Example

In the following example, the CallId plugin for the Ktor client is configured to generate a new call ID and add it to the header:

val client = HttpClient(CIO) { install(CallId) { generate { "call-id-client" } addToHeader(HttpHeaders.XRequestId) } }

The plugin uses the coroutine context to get a call ID and utilizes the generate() function to generate a new one. The first non-null call ID is then applied to the request header using the addToHeader() function.

In a Ktor server, the call ID can then be retrieved from the header using the retrieve functions from the CallId plugin for the server.

install(CallId) { retrieveFromHeader(HttpHeaders.XRequestId) }

In this way the Ktor server retrieves the ID of the specified header of the request and applies it to the callId property of the call.

For the full example, see client-call-id

Last modified: 09 October 2023