@@ -229,10 +229,11 @@ which lets you deal with profiles and `Environment` for customizing
229
229
how beans are registered.
230
230
231
231
In the following example notice that:
232
- - Type inference usually allows to avoid specifying the type for bean references like `ref("bazBean")`
233
- - It is possible to use Kotlin top level functions to declare beans using callable references like `bean(::myRouter)` in this example
234
- - When specifying `bean<Bar>()` or `bean(::myRouter)`, parameters are autowired by type
235
- - The `FooBar` bean will be registered only if the `foobar` profile is active
232
+
233
+ * Type inference usually allows to avoid specifying the type for bean references like `ref("bazBean")`
234
+ * It is possible to use Kotlin top level functions to declare beans using callable references like `bean(::myRouter)` in this example
235
+ * When specifying `bean<Bar>()` or `bean(::myRouter)`, parameters are autowired by type
236
+ * The `FooBar` bean will be registered only if the `foobar` profile is active
236
237
237
238
[source,kotlin,indent=0]
238
239
----
@@ -290,20 +291,23 @@ for more details and up-to-date information.
290
291
== Web
291
292
292
293
294
+ === Router DSL
293
295
294
- === WebFlux Router DSL
295
-
296
- Spring Framework comes with a Kotlin router DSL available in two flavors:
296
+ Spring Framework comes with a Kotlin router DSL available in 3 flavors:
297
297
298
- - Reactive with {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-router-function-dsl/[router { }]
299
- - <<Coroutines>>
298
+ * WebMvc.fn {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.servlet.function/router.html[router { }]
299
+ * WebFlux.fn <<web-reactive#webflux-fn, Reactive>> {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/router.html[router { }]
300
+ * WebFlux.fn <<Coroutines>> {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]
300
301
301
- These DSL let you use the <<web-reactive#webflux-fn, WebFlux functional API>> to write clean
302
- and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:
302
+ These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:
303
303
304
304
[source,kotlin,indent=0]
305
305
----
306
- val myRouter: RouterFunction<ServerResponse> = router {
306
+ @Configuration
307
+ class RouterRouterConfiguration {
308
+
309
+ @Bean
310
+ fun mainRouter(userHandler: UserHandler) = router {
307
311
accept(TEXT_HTML).nest {
308
312
GET("/") { ok().render("index") }
309
313
GET("/sse") { ok().render("sse") }
@@ -319,46 +323,56 @@ and idiomatic Kotlin code to build a `RouterFunction` instance as the following
319
323
}
320
324
resources("/**", ClassPathResource("static/"))
321
325
}
326
+ }
322
327
----
323
328
324
329
NOTE: This DSL is programmatic, meaning that it allows custom registration logic of beans
325
330
through an `if` expression, a `for` loop, or any other Kotlin constructs. That can be useful
326
331
when you need to register routes depending on dynamic data (for example, from a database).
327
332
328
- See https://github.com/mixitconf/mixit/tree/dafd5ccc92dfab6d9c306fcb60b28921a1ccbf79/src/main/kotlin/mixit/web/routes[MiXiT project routes]
329
- for a concrete example.
333
+ See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
330
334
331
335
332
336
333
337
=== Coroutines
334
338
335
339
As of Spring Framework 5.2, https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] support
336
- is provided via extensions for WebFlux client and server functional API. A dedicated
337
- {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-co-router-function-dsl/[`coRouter { }`]
338
- router DSL is also available.
340
+ is provided via:
341
+
342
+ * https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return value support in Spring WebFlux annotated `@Controller`
343
+ * Suspending function support in Spring WebFlux annotated `@Controller`
344
+ * Extensions for WebFlux {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.client/index.html[client] and {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/index.html[server] functional API.
345
+ * WebFlux.fn {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]
339
346
340
347
Coroutines extensions use `await` prefix or `AndAwait` suffix, and most are using similar
341
- names to their reactive counterparts, except `exchange` in `WebClient.RequestHeadersSpec`
342
- which translates to `awaitResponse`.
348
+ names to their reactive counterparts.
343
349
344
350
[source,kotlin,indent=0]
345
351
----
346
- fun routes(userHandler: UserHandler): RouterFunction<ServerResponse> = coRouter {
347
- GET("/", userHandler::listView)
348
- GET("/api/user", userHandler::listApi)
352
+ @Configuration
353
+ class RouterConfiguration {
354
+
355
+ @Bean
356
+ fun mainRouter(userHandler: UserHandler) = coRouter {
357
+ GET("/", userHandler::listView)
358
+ GET("/api/user", userHandler::listApi)
359
+ }
349
360
}
361
+ ----
350
362
363
+ [source,kotlin,indent=0]
364
+ ----
351
365
class UserHandler(builder: WebClient.Builder) {
352
366
353
367
private val client = builder.baseUrl("...").build()
354
368
355
369
suspend fun listView(request: ServerRequest): ServerResponse =
356
370
ServerResponse.ok().renderAndAwait("users", mapOf("users" to
357
- client.get().uri("...").awaitResponse ().awaitBody<User>()))
371
+ client.get().uri("...").awaitExchange ().awaitBody<User>()))
358
372
359
373
suspend fun listApi(request: ServerRequest): ServerResponse =
360
374
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).bodyAndAwait(
361
- client.get().uri("...").awaitResponse ().awaitBody<User>())
375
+ client.get().uri("...").awaitExchange ().awaitBody<User>())
362
376
}
363
377
----
364
378
0 commit comments