microservices and happier developers! Expressiveness and safety for building GraphQL APIs (with Java interoperability!) High-load, lock-free software with Kotlin Coroutines
db.findMessages() fun post(message: Message){ db.save(message) } } interface MessageRepository : CrudRepository<Message, String>{ @Query("select * from messages") fun findMessages(): List<Message> } @Table("MESSAGES") data class Message(@Id val id: String?, val text: String)
db.findMessages() fun post(message: Message){ db.save(message) } } interface MessageRepository : CrudRepository<Message, String> { @Query("select * from messages") fun findMessages(): List<Message> } @Table("MESSAGES") data class Message(@Id val id: String?, val text: String)
db.findMessages() fun post(message: Message){ db.save(message) } } interface MessageRepository : CrudRepository<Message, String>{ @Query("select * from messages") fun findMessages(): List<Message> } @Table("MESSAGES") data class Message(@Id val id: String?, val text: String)
db.findMessages() fun post(message: Message){ db.save(message) } } interface MessageRepository : CrudRepository<Message, String>{ @Query("select * from messages") fun findMessages(): List<Message> } @Table("MESSAGES") data class Message(@Id val id: String?, val text: String) Not to be used with JPA!
plugins to the rescue! * Data classes don’t play well with JPA * Use usual classes with JPA Important for starters * Use start.spring.io to generate con fi gs
db.query("select * from messages") { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id) { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun post(message: Message){ db.update("insert into messages values ( ?, ? )", message.id ?: message.text.uuid(), message.text) } } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id, { rs, _ -> Message(rs.getString("id"), rs.getString("text")) }) vararg is not at the last position
db.query("select * from messages") { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id) { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun post(message: Message){ db.update("insert into messages values ( ?, ? )", message.id ?: message.text.uuid(), message.text) } } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id, { rs, _ -> Message(rs.getString("id"), rs.getString("text")) }) Lambda expression is at the last position
db.query("select * from messages") { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id) { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun post(message: Message){ db.update("insert into messages values ( ?, ? )", message.id ?: message.text.uuid(), message.text) } } Passing trailing lambda as a parameter to the function
db.query("select * from messages") { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun findMessageById(id: String): List<Message> = db.query("select * from messages where id = ?", id) { rs, _ - > Message(rs.getString("id"), rs.getString("text")) } fun post(message: Message){ db.update("insert into messages values ( ?, ? )", message.id ?: message.text.uuid(), message.text) } } This is an extension function For the existing Java class in the Spring framework
data initialization .. . ") val repository = ref<MessageRepository>() repository.save(Message(text = "this is the first message!")) repository.save(Message(text = "this is the second")) } } } @SpringBootApplication class DemoApplication fun main(args: Array<String>) { runApplication<DemoApplication>(*args) { this.addInitializers(beans) } }
} } val beans = beans { bean { CommandLineRunner { println("start data initialization .. . ") val repository = ref<MessageRepository>() repository.save(Message(text = "this is the first message!")) repository.save(Message(text = "this is the second } } }
Data classes Rei fi ed generics Top-level functions Named arguments Operator overloading Trailing lambdas Extension functions Functional literal with receiver Nullable types Support for JSR-305
fun main() { embeddedServer(Netty, port = 8080) { routing { get("/") { call.respondText("Hello World!") } } }.start(wait = true) } Start an embedded server with Netty engine on port 8080