Kotlin 1.4 Online Event
October 15, 2020
@sdeleuze
The State of Kotlin
Support in Spring
Sébastien Deleuze
Spring is the server-side leader on the JVM
Source: a Picture of Java in 2020, JetBrains
First class support for Java and Kotlin
More Spring Boot projects
generated with Kotlin each year.
Lets focus on Kotlin today
Getting started
Start your project on https://start.spring.io
Minimal Spring Boot Kotlin application
Gradle Kotlin DSL
Also available in IDEs
IntelliJ IDEA Ultimate VS code
Follow the tutorial on https://spring.io/guides
Spring Framework documentation in Kotlin
Choose your style
Choose your web server stack
Do I need
asynchronous
or reactive
programming?
Spring MVC
Tomcat
Spring WebFlux
with Coroutines
Netty
No
Yes
Persistence
Spring Data
JPA
JDBC
Redis
Mongo
...
Spring Data
Reactive
with Coroutines
R2DBC
Redis
Mongo
...
Persistence
Choose your programming model
Do you prefer annotations?
@RestController
@RequestMapping("/api/article")
class ArticleController(private val repository: ArticleRepository) {
@GetMapping("/")
fun findAll() = repository.findAllByOrderByAddedAtDesc()
@GetMapping("/{slug}")
fun findOne(@PathVariable slug: String) =
repository.findBySlug(slug) ?:
throw ResponseStatusException(NOT_FOUND)
}
Or functional APIs?
@Bean
fun route(repository: ArticleRepository) = router {
"/api/article".nest {
GET("/") {
ok().body(repository.findAllByOrderByAddedAtDesc())
}
GET("/{slug}") {
val slug = it.pathVariable("slug")
val article = repository.findBySlug(slug) ?:
throw ResponseStatusException(NOT_FOUND)
ok().body(article)
}
}
}
Spring supports both,
so up to you.
Coroutines
Allow to go reactive with a
great trade-off between
imperative and functional
programming.
Coroutines are the default way to
go reactive in Spring with Kotlin.
First class Coroutines support
Spring WebFlux
Spring MVC (new in Spring Boot 2.4
Spring Data Reactive
Spring Messaging (RSocket)
Spring Vault
Suspending functions
Spring MVC and WebFlux
@GetMapping("/api/banner")
suspend fun suspendingEndpoint(): Banner {
delay(10)
return Banner("title", "Lorem ipsum")
}
Flow
Spring MVC and WebFlux
@GetMapping("/banners")
suspend fun flow(): Flow<Banner> = client.get()
.uri("/messages")
.accept(MediaType.TEXT_EVENT_STREAM)
.retrieve()
.bodyToFlow<String>()
.map { Banner("title", it) }
Multiplatform
Multiplatform
kotlinx.serialization
kotlinx.serialization support
New in Spring Boot 2.4
More lightweight than Jackson
Designed for Kotlin
Multiplatform serialization
Allows same code for model and validation
across server, frontend and mobile!
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude(module = "spring-boot-starter-json")
}
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0")
Kotlin/JS
Kotlin/WASM has a huge potential
RSocket
RSocket
Reactive
Streams
RSocket
Reactive
Streams
Reactive
Streams
RSocket
.Python
.NET
Go
C++
JavaScript
Reactive
Streams
RSocket
Kotlin
Java
Reactor
RSocket support in Spring messaging
class MessageHandler(private val builder: RSocketRequester.Builder) {
// ...
suspend fun stream(request: ServerRequest): ServerResponse {
val requester = builder
.dataMimeType(APPLICATION_CBOR)
.connectTcpAndAwait("localhost", 9898)
val replies = requester
.route("bot.messages")
.dataWithType(processor)
.retrieveFlow<Message>()
val broadcast = requester.route("bot.broadcast").retrieveFlow<Message>()
val messages = flowOf(replies, processor.asFlow(), broadcast).flattenMerge()
return ok().sse().bodyAndAwait(messages)
}
}
rsocket-kotlin
Other key points
100% of Spring Framework API
with null-safety annotations
→ no NPE for Spring applications
written in Kotlin
ConfigurationProperties data classes
@ConstructorBinding
@ConfigurationProperties("blog")
data class BlogProperties(val title: String, val banner: Banner) {
data class Banner(val title: String? = null, val content: String)
}
Spring Security Kotlin DSL
New in Spring Security 5.4
override fun configure(http: HttpSecurity) {
http {
authorizeRequests {
authorize("/css/**", permitAll)
authorize("/user/**", hasAuthority("ROLE_USER"))
}
formLogin {
loginPage = "/log-in"
}
}
}
Spring Boot native applications
With GraalVM native
Spring Boot
application
EXE
Native
executable
Lightweight
container
image
JVM and native executables offer different
trade-offs
Instant startup and cheaper hosting
Spring Boot on Native,
1 vCPU, 256M RAM
Spring Boot on JVM,
4 vCPU, 1G RAM
Spring support for native executables
GraalVM fixes
and improvements
Incubating support in
spring-graalvm-native plugin
(Spring Boot 2 baseline)
First class support
in Spring Boot 3
Today
Dec 2020
Beta
Spring Boot 3
release
Demo
Whats next?
Programmatic configuration for Spring Boot using a Kotlin DSL
Spring Fu is an incubator for a functional
flavor of Spring Boot
KoFu JaFu
What is the same than Spring Boot?
https://start.spring.io
Based on Spring Boot infrastructure
Spring configuration for the JVM ecosystem
Dependency management
Starters
Actuators
Standalone executable JAR or container deployment
What changes?
Conventions and automatic
configuration
Annotations-based configuration
Reflection-based infrastructure
Production ready
Explicit declaration
Functional configuration
Lambda-based infrastructure
Incubating
Spring Boot regular flavor
Spring Fu flavor
Spring Boot configured with KoFu
val app = webApplication {
beans {
bean<SampleService>()
bean<SampleHandler>()
}
webMvc {
port = if (profiles.contains("test")) 8181 else 8080
router {
val handler = ref<SampleHandler>()
GET("/", handler::hello)
GET("/api", handler::json)
}
converters {
string()
jackson {
indentOutput = true
}
}
}
}
fun main() {
app.run()
}
Links
https://start.spring.io
https://spring.io/guides/tutorials/spring-boot-kotlin/
https://github.com/spring-projects-experimental/spring-graalvm-native
https://github.com/spring-projects-experimental/spring-fu
@sdeleuze
Thanks!
Have a nice Kotlin!