Spring Fu is an incubator for Kofu (Ko for Kotlin, fu for functional), which provides a Kotlin API to configure Spring Boot applications programmatically with following characteristics:
-
Explicit configuration via a Kotlin DSL instead of auto-configuration
-
Leverages Spring Framework 5 functional bean configuration instead of annotations
-
Allows to define custom configuration slices (useful for more focused and efficient testing)
-
Great discoverability via code auto-complete
-
Web functional routing instead of
@Controller
available in 3 flavors:-
WebMvc.fn (functional variant Spring MVC)
-
WebFlux.fn with Reactor declarative-style API (
Mono
andFlux
) -
WebFlux.fn with Coroutines imperative-style API (using suspending functions and Kotlin
Flow
)
-
-
Persistence via Spring Data functional APIs like:
-
Spring Data JDBC
JdbcAggregateOperations
-
Spring Data NoSQL
*Operations
APIs for MongoDB, Redis and Cassandra
-
Configuration via Spring Security
security { }
DSL (WIP) -
Fast startup and low memory consumption
It is not intended to be used in production yet, but rather to incubate and get feedback and contributions from the community in order to hopefully reach a point where it can be integrated as part of Spring Boot.
If you are interested in running Spring application as GraalVM native images see this dedicated Spring Framework issue.
Here is a minimal sample application that is leveraging WebMvc.fn:
val app = application(WebApplicationType.SERVLET) {
logging {
level = LogLevel.DEBUG
}
beans {
bean<SampleService>()
}
webMvc {
port = if (profiles.contains("test")) 8181 else 8080
router {
val service = ref<SampleService>()
GET("/") {
ok().body(service.generateMessage())
}
GET("/api") {
ok().body(Sample(service.generateMessage()))
}
}
converters {
string()
jackson {
indentOutput = true
}
}
}
}
data class Sample(val message: String)
class SampleService {
fun generateMessage() = "Hello world!"
}
fun main() {
app.run()
}
To use WebFlux.fn instead
-
Use
WebApplicationType.REACTIVE
instead ofWebApplicationType.SERVLET
-
Use
webFlux { }
instead ofwebMvc { }
-
Use
spring-boot-starter-webflux
starter instead ofspring-boot-starter-web
-
Use
coRouter { }
instead ofrouter { }
if you want to use Coroutines instead of Reactor API
Kofu is technically just a dependency you add to your Spring Boot project.
dependencies {
implementation("org.springframework.fu:spring-fu-kofu:0.x")
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}
-
Create a Spring
2.2.0.M3
project on start.spring.io with the "Web" or "Reactive web" starter -
Add the
org.springframework.fu:spring-fu-kofu:0.1
dependency -
Modify the generated
DemoApplication.kt
file as following:
package com.sample
import org.springframework.fu.kofu.application
val app = application(...) {
...
}
fun main() {
app.run()
}
See sample projects here.
In addition to the whole Spring and Reactor teams, special credits to:
-
Juergen Hoeller for his support on Kotlin and the functional bean registration API
-
Arjen Poutsma for creating the WebFlux functional API
-
Thomas Girard for its spring-webflux-kotlin-dsl experiment that initially demonstrated this approach was possible
-
Konrad Kaminski for his awesome spring-kotlin-coroutine project
-
Dave Syer for his work on benchmarks, GraalVM support and functional bean registration applied to Boot
-
The whole Spring Boot team