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

  1. @Get("/simple", produces = [MediaType.TEXT_PLAIN])
  2. suspend fun simple(): String { (1)
  3. return "Hello"
  4. }
1The function is marked as suspend, though in reality it won’t be suspended.

Controller suspend function example

  1. @Get("/delayed", produces = [MediaType.TEXT_PLAIN])
  2. suspend fun delayed(): String { (1)
  3. delay(1) (2)
  4. return "Delayed"
  5. }
1The function is marked as suspend.
2The delay is called to make sure that a function is suspended and the response is returned from a different thread.

Controller suspend function example

  1. @Status(HttpStatus.CREATED) (1)
  2. @Get("/status")
  3. suspend fun status(): Unit {
  4. }
1suspend function also works when all we want is to return a status.

Controller suspend function example

  1. @Status(HttpStatus.CREATED)
  2. @Get("/statusDelayed")
  3. suspend fun statusDelayed(): Unit {
  4. delay(1)
  5. }

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

  1. @Get(value = "/headlinesWithFlow", processes = [MediaType.APPLICATION_JSON_STREAM])
  2. internal fun streamHeadlinesWithFlow(): Flow<Headline> = (1)
  3. flow { (2)
  4. repeat(100) { (3)
  5. with (Headline()) {
  6. text = "Latest Headline at " + ZonedDateTime.now()
  7. emit(this) (4)
  8. delay(1_000) (5)
  9. }
  10. }
  11. }
1A method streamHeadlinesWithFlow is defined that produces application/x-json-stream
2A Flow is created using flow
3This Flow will emit 100 messages
4Emitting will happend with emit suspend function
5There will be a 1 second delay between messages

A streaming client can simply return a Flow, for example:

Streaming client with Flow

  1. import io.micronaut.http.MediaType
  2. import io.micronaut.http.annotation.Get
  3. import io.micronaut.http.client.annotation.Client
  4. import kotlinx.coroutines.flow.Flow
  5. @Client("/streaming")
  6. interface HeadlineFlowClient {
  7. @Get(value = "/headlinesWithFlow", processes = [MediaType.APPLICATION_JSON_STREAM]) (1)
  8. fun streamFlow(): Flow<Headline> (2)
  9. }
1The @Get method is defined as processing responses of type APPLICATION_JSON_STREAM
2A Flow is used as the return type