13.3.5 Coroutines Support
Kotlin coroutines allow you to create asynchronous applications with imperative style code. A Micronaut’s controller action can be a suspend
function:
Controller suspend function example
@Get("/simple", produces = [MediaType.TEXT_PLAIN])
suspend fun simple(): String { (1)
return "Hello"
}
1 | The function is marked as suspend , though in reality it won’t be suspended. |
Controller suspend function example
@Get("/delayed", produces = [MediaType.TEXT_PLAIN])
suspend fun delayed(): String { (1)
delay(1) (2)
return "Delayed"
}
1 | The function is marked as suspend . |
2 | The delay is called to make sure that a function is suspended and the response is returned from a different thread. |
Controller suspend function example
@Status(HttpStatus.CREATED) (1)
@Get("/status")
suspend fun status(): Unit {
}
1 | suspend function also works when all we want is to return a status. |
Controller suspend function example
@Status(HttpStatus.CREATED)
@Get("/statusDelayed")
suspend fun statusDelayed(): Unit {
delay(1)
}
You can also use Flow
type for streaming server and client. A streaming controller can return Flow
, for example:
Streaming JSON on the Server with Flow
@Get(value = "/headlinesWithFlow", processes = [MediaType.APPLICATION_JSON_STREAM])
internal fun streamHeadlinesWithFlow(): Flow<Headline> = (1)
flow { (2)
repeat(100) { (3)
with (Headline()) {
text = "Latest Headline at " + ZonedDateTime.now()
emit(this) (4)
delay(1_000) (5)
}
}
}
1 | A method streamHeadlinesWithFlow is defined that produces application/x-json-stream |
2 | A Flow is created using flow |
3 | This Flow will emit 100 messages |
4 | Emitting will happen with emit suspend function |
5 | There will be a 1 second delay between messages |
A streaming client can simply return a Flow
, for example:
Streaming client with Flow
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.annotation.Client
import kotlinx.coroutines.flow.Flow
@Client("/streaming")
interface HeadlineFlowClient {
@Get(value = "/headlinesWithFlow", processes = [MediaType.APPLICATION_JSON_STREAM]) (1)
fun streamFlow(): Flow<Headline> (2)
}
1 | The @Get method is defined as processing responses of type APPLICATION_JSON_STREAM |
2 | A Flow is used as the return type |