93 lines
3.1 KiB
Plaintext
93 lines
3.1 KiB
Plaintext
[[kotlin-web]]
|
|
= Web
|
|
|
|
|
|
|
|
[[router-dsl]]
|
|
== Router DSL
|
|
|
|
Spring Framework comes with a Kotlin router DSL available in 3 flavors:
|
|
|
|
* xref:web/webmvc-functional.adoc[WebMvc.fn DSL] with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]
|
|
* xref:web/webflux-functional.adoc[WebFlux.fn Reactive DSL] with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]
|
|
* xref:languages/kotlin/coroutines.adoc[WebFlux.fn Coroutines DSL] with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]
|
|
|
|
These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:
|
|
|
|
[source,kotlin,indent=0]
|
|
----
|
|
@Configuration
|
|
class RouterRouterConfiguration {
|
|
|
|
@Bean
|
|
fun mainRouter(userHandler: UserHandler) = router {
|
|
accept(TEXT_HTML).nest {
|
|
GET("/") { ok().render("index") }
|
|
GET("/sse") { ok().render("sse") }
|
|
GET("/users", userHandler::findAllView)
|
|
}
|
|
"/api".nest {
|
|
accept(APPLICATION_JSON).nest {
|
|
GET("/users", userHandler::findAll)
|
|
}
|
|
accept(TEXT_EVENT_STREAM).nest {
|
|
GET("/users", userHandler::stream)
|
|
}
|
|
}
|
|
resources("/**", ClassPathResource("static/"))
|
|
}
|
|
}
|
|
----
|
|
|
|
NOTE: This DSL is programmatic, meaning that it allows custom registration logic of beans
|
|
through an `if` expression, a `for` loop, or any other Kotlin constructs. That can be useful
|
|
when you need to register routes depending on dynamic data (for example, from a database).
|
|
|
|
See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
|
|
|
|
|
|
|
|
[[mockmvc-dsl]]
|
|
== MockMvc DSL
|
|
|
|
A Kotlin DSL is provided via `MockMvc` Kotlin extensions in order to provide a more
|
|
idiomatic Kotlin API and to allow better discoverability (no usage of static methods).
|
|
|
|
[source,kotlin,indent=0]
|
|
----
|
|
val mockMvc: MockMvc = ...
|
|
mockMvc.get("/person/{name}", "Lee") {
|
|
secure = true
|
|
accept = APPLICATION_JSON
|
|
headers {
|
|
contentLanguage = Locale.FRANCE
|
|
}
|
|
principal = Principal { "foo" }
|
|
}.andExpect {
|
|
status { isOk }
|
|
content { contentType(APPLICATION_JSON) }
|
|
jsonPath("$.name") { value("Lee") }
|
|
content { json("""{"someBoolean": false}""", false) }
|
|
}.andDo {
|
|
print()
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[kotlin-multiplatform-serialization]]
|
|
== Kotlin multiplatform serialization
|
|
|
|
{kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is
|
|
supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.
|
|
|
|
To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.
|
|
With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since
|
|
Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.
|
|
With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,
|
|
if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manually.
|
|
|
|
|
|
|
|
|