[[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 dependencies
and plugin. With Spring MVC and WebFlux, Kotlin serialization is configured by default if it is in the classpath and
other variants like Jackson are not. If needed, configure the converters or codecs manually.
