Transcript
Lee: Welcome to Kotlin: More than Just Android. My name is Justin Lee. I'm a developer at Red Hat. I work on the Quarkus microservice MicroProfile based framework. I'm also a huge Kotlin fan. I've been a fan of Kotlin for many years now. I'm really excited to see how big it's growing and continues to evolve in some really amazing spaces. Kotlin, was really the very first language that enticed me away from writing in Java. I'm a Java champion. I've been doing Java since 1996. For me, Kotlin was the first language that felt really good enough to migrate all my stuff to. I did that several years ago. I moved my first big project over to Kotlin in 2015. I've been trying to do as much as I can with it ever since. I'm one of the co-leaders at the New York City Kotlin meetup. Many of the Kotlin devs I talk to only do Android. They've never really written any backend applications. The thought of writing non-Android applications in Kotlin just hasn't occurred to a lot of them, because why would they. That's a little frustrating for me, a little disappointing, because I personally love Kotlin, obviously, but I've never written a single Android app. There's so much that Kotlin has to offer on the backend, but never really gets considered for a lot of people.
Outline
What I want to do is I want to showcase some of the more prominent non-Android options for Kotlin on the backend. I just want to go through a quick whirlwind tour of some of the bigger players, to give you an idea of what's out there. We can talk some options there. The beautiful thing about Kotlin is it was designed to interoperate with Java as seamlessly as possible. Virtually, any Java library out there, whether it's a framework or a library or whatever it might be, you can use it in Kotlin with very little problems. You can pretty much use any framework you want to write Kotlin on the backend, but these options give specific Kotlin goodness to the mix and make it a little bit simpler to use on the backend. We'll look at some of that stuff. What I'm hoping to do is to whet your appetite for Kotlin on the backend, if you haven't considered it yet, because it is a great option. What I really hope to do is to inspire you just to write Kotlin everywhere you can. Because there's really no technical reason you shouldn't. It's a great choice for whatever your computing needs might happen to be.
I wanted to go through a series of options you have for running stuff on the backend. Primarily, we're going to look at web microservice frameworks, because it's typically at least the entry point on the backend when you want to start talking about this or that. That's what we're going to look at. Then we'll look at some desktop stuff, then maybe take a brief peek at some of the things.
Web Frameworks - Ktor
Let's start talking web frameworks. I would be remiss if I didn't start with the most Kotlin-y version of that answer. The definitive answer there seems to be this library called Ktor, which started off as an early DSL experiment for this or that, and has evolved into a super feature rich framework. It had probably more features than I can process at this moment. If you want something like purely Kotlin and written for Kotlin by Kotlin people, then Ktor is where you want to go. You can find it at ktor.io. Because it's written in Kotlin and for Kotlin and by Kotlin people, all the rich Kotlin goodness comes out in how the language plays into the library.
The Simplest Ktor Application
For example, if you want to do, as the website says, the simplest Ktor application, in this case we're going to do, fun main, which is the equivalent of public static void main, from the Java world. In Kotlin, you just need, fun main. You can take an array of string as arguments if you want, or not. Most people I think don't probably use those arguments overly much. Regardless, this is the simplest way that you can start a Ktor application. In this case, they're defining an embedded server, they're using Netty, running on port 8000. As you can see here, they're parsing a lambda to this embedded server. In here, what they're defining is the routing, so all of your route endpoints. If you're coming from the JAX-RS world, this would be like your @Path. You're going to have @GET, @PUT, @POST, whatever. Ktor defines a very handy DSL to do this. There's the starting point here. We're defining the routing for this embedded server, and we're parsing in yet another lambda. We're going to define a get endpoint on the route, and all it does is it returns the response text of Hello, World. There's some internal stuff here, where a call comes from everything. This is what a very basic Ktor application looks like.
Define Multiple Route Handlers
You can get a little bit more complicated in your routing, if you so choose. Here, for example, there are multiple endpoints, a get on /customer with an ID as URL parameters that can be used inside the function body there. There's a post on the /customer endpoint, and then it gets again, an order instead of ID. You can define them like this. Also, if you want to, you can group them together. We're going to define a route on /customer with a get endpoint and a post endpoint. You can put your various handling logic in those particular functions, depending on what the incoming HTTP verb looks like. You can nest them, of course, if you wanted to do so. Then you can use extension functions if you want. You can define your functions elsewhere. If you had everything defined in one giant routing block, your simple application suddenly becomes very large just to do the starting point. You can map all those out into separate functions and separate classes, if you like.
Building Web Applications with Spring Boot and Kotlin
If you've done Java backend development, then you've probably used Spring Boot. If you haven't, you know someone who has. This is the obvious second step, because it is the biggest player probably in the Java world, at least in the microservices universe. Spring Boot added Kotlin support, two or three years now. They have some rather robust options for you. If you've used Spring Boot, this should all look very familiar to you. They have their Spring Initializr. You can come in, define whichever options you want, you need Gradle or Maven. You can use Kotlin, you can use Java. We're here to learn Kotlin, so why wouldn't we? Just like every other Spring Boot application, just choose which modules you want, which extensions, and then generate. It will generate a whole new package for you. You load it up, run it, and suddenly you're running Kotlin on the web. Super handy. If you're fiddling with Spring Boot, it's definitely a great place to start.
Quarkus - Creating Your First Application
Next is Quarkus, which is near and dear to my heart. I happen to work on the Quarkus team. I do want to mention Quarkus, because it also has Kotlin support, part of my job is to enhance and render out the Kotlin support inside Quarkus. If you're not too keen on getting tied up into the Spring ecosystem, which some people are for various reasons, then Quarkus is a great option. It uses RESTEasy and Hibernate. If you're familiar with CDI for MicroProfile, it all uses standard Jakarta EE and MicroProfile, so it's a library. It should all be very familiar to you. Even though most of it is not written in Kotlin, as is the case with Spring Boot as well, because Kotlin is designed to interop with Java, it's very natural to use Java libraries from Kotlin for the most part. Both Spring Boot and Quarkus do provide a number of Kotlin idiomatic ways to interact with the system. Those of course will increase and improve over time. Quarkus is a great choice.
Micronaut
Another one is Micronaut, which is also quite popular. A lot of people like to use that if they're not on Spring Boot or Quarkus. They have rather robust Kotlin support as well. They also have support for Ktor. If you'd rather use Ktor as the underlying transport layer instead of, I believe it uses Netty by default, you can actually use Ktor and wire in that way. If you're familiar with Micronaut, and all of its injections and annotations, and lifecycle support and everything, you can still use all that on top of Ktor. Which has some interesting multi-threaded concurrency capabilities that you don't necessarily see as a developer, but you will definitely experience them on the Ops side, because it's quite nice.
If I had to pick the top three or four web frameworks, that's what I would look to, for Kotlin. There are dozens of more niche or boutique frameworks. I don't say that to denigrate any of them. There's some amazing work going on in terms of like pushing the boundaries with Kotlin and DSLs, and such. They're just not as popular, so finding support or someone who also knows those libraries might be a little bit harder, but it might be worth it to try some of those smaller ones as well because they might really scratch your particular itch.
JavaFX and TornadoFX
Moving away from the web to the desktop. If you've ever talked about Java in the desktop, of course, it was Swing for a long time, but the new hotness is JavaFX. I've seen some amazing JavaFX applications written doing some pretty stellar work in aerospace work. For example, putting things in orbit around Jupiter. That's not an exaggeration, it's pretty stellar. However, there is a library called TornadoFX, which provides a number of Kotlin extension functions and DSLs and convenience methods for building your JavaFX applications in a much more idiomatic, Kotlin way, that helps reduce the boilerplate needed to build out such an application. The documentation is fairly extensive. You have to build your layout, for example. It might look like this, which is a nice little DSL, creating your virtual box and button. You can define the action on it. It pops out like this. These are all basic examples, of course. It really leverages the power of Kotlin to reduce the amount of code you have to write in order to build your JavaFX applications.
Jetpack Compose for Desktop
One I wanted to mention, even though I'm skirting dangerously close to Android, is this thing from JetBrains called Jetpack Compose. It originally, as I understand it, started off as an Android application framework for building Android applications for Android devices. It has since expanded to the desktop, which is now in alpha, according to the website. I thought it was beyond that. The website still says alpha at least. It provides fast reactive desktop UIs for Kotlin. It's based on some stuff from Google and JetBrains. As I understand it, they're working together to build this framework for building applications. What makes this really stellar and what might make it interesting to those of you who write desktop applications is that you can use much of the same code base for the desktop version of the application and the mobile application version of it. You can share a whole lot of the code in between each module. Then there's also a third component of this which is not as far along, as the mobile device and the desktop. There's also work being done for web. You can actually build the same application for desktop for Android and for the web. Even though, obviously, some of the UI components won't necessarily carry over much of the logic, and the wiring behind the scenes can be reused. Then you just have to swap out perhaps certain UI elements to make something a little bit more natural for whichever platform you're building on. Then you can share all the rest of the code in between the projects in one code base. That's Jetpack Compose.
Resources
This website is called Awesome Kotlin, and it has a number of links and resources off to everything. Just the base, awesome tab has courses and books. You scroll down, and you see all these libraries and frameworks. Here's Ktor, of course. Here's http4k which has 1700 stars on GitHub, which is nothing to laugh at. A lot of work is being done with Kotlin in data science, which makes me happy. If you're not a huge fan of Python, for example, you can actually use Kotlin with Jupyter Notebooks with Kotlin Jupyter. There's work being done there. There are some specific testing frameworks you can use to make it a little bit more Kotlin friendly inside your test. There's some database specific, and JetBrains exposed as a nice typesafe DSL over SQL queries in Kotlin, which is very interesting. Some custom dependency injection, this and that. The list just goes on. If you click under resources, you can get the latest hotness, depending on what you're looking for in resources and courses.
I also wanted to point out this last tab, especially. I just wanted to show you all the user groups around. Hopefully, there's one near you wherever you happen to live. In the time of COVID, most of them are online in here. A lot of them are online. They have the resources to do that. Please do find a meetup user group somewhere nearby and just hang out and see what the vibe is, and learn. You don't have to actually write Kotlin code. You don't have to commit to it. Join a group. You can just join one and see what's happening.
I want to leave a couple of resources. Kotlinlang.org is the primary website. All the official documentation is there, tutorials. It's all there, all you could ever want. There's also play.kotlinlang.org, where you can actually run code in your browser, so you can experiment with Kotlin code without having to install anything. If you would like to use Slack, there's a Slack workspace for Kotlin that has over 30,000 people in various channels. It is a great resource. There's dozens of different topics you can follow and create your own. If you're more of the IRC type like myself, there is #Kotlin on FreeNode, where you will find me hanging out most days. Of course, Awesome Kotlin with all those links. There's a ton of information there.
Questions and Answers
Ruiz: Kotlin 1.5 was just released, May 5. What can you tell us about the new release? What is exciting for you?
Lee: One of the things that I've been looking forward to, is they actually rewrote the entire compiler, and that doesn't really necessarily affect developers as such. I've been eyeballing it, because one of the things that I do on Quarkus, which is one of the reasons I brought up in the talk, was I'm the guy adding support for Kotlin-y sorts of things inside Quarkus. We do a lot of bytecode manipulation. I was a little worried that they would change how that bytecode gets generated, and it would just completely mangle everything I work on, but so far, so good. I'm in the process of actually now trying to port it over, and tests are failing weirdly, so who knows. I haven't actually gone over the list of things to look at, because I don't get to write Kotlin that much in my day job just yet. I do try to do in my side projects, and I have some open source stuff that I'm going to migrate to that.
Ruiz: Actually about that, what about Morphia and Kotlin, tell me.
Lee: I used to work for MongoDB, and there was this layer called Morphia. I like to describe it as Hibernate but for Mongo, so you annotate all your Java objects, and Morphia shells it back and forth just like Hibernate would do. There is support in Morphia for Kotlin, actually, in this upcoming release that hopefully will be out in the next week or two. There's a specific module for supporting data classes inside Morphia, because those are slightly different from a reflection standpoint. I'm adding more support. At some point, I'm going to port all of Morphia probably to Kotlin, because I like writing in it. I'm trying not to leave anyone behind. Kotlin is really great. It is designed to interop with Java. If you're not careful, you can expose the fact that it's a Kotlin library to your Java developers, because there's a certain way that Kotlin does the magic, especially around like generics that can sometimes leak out, if you're not careful.
Scala is really bad about that. One of the questions was, why Kotlin over Scala? Scala is a fine language. I've tried to use it, and I've tried to like it, but it's never been a professional thing for me. If you've ever tried to use a Scala library from Java, it's very obvious that the library was not written in Java. It's really hard to use. Whereas Kotlin, that's not the case. You can run it from Java, you'd see something like, what is that? It's usually generally good about creating Java friendly APIs. One of the things that Kotlin has, and I really liked it, I hope Java gets someday, but probably won't, is named parameters and default parameters. When you define a function, you can define default values for a parameter. If you don't parse an argument for that when you call it, the compiler will inject it for you. You could default all your parameters away in your declaration. When you call it, you can just call it with no parameters, because the compiler will insert things for you when it builds. From Java, that gets weird, because there's just the one method that takes all the parameters, and so you lose some of that defaulted parameters. There's an annotation you can use that Kotlin will actually generate multiple overloads. It'll start from the very right-hand side and start peeling off the defaulted parameters, so that if there are four parameters with defaults, you get four or five methods. One that takes all the parameters, and then one that takes three, then two, then one, and nothing. You get that same feeling from Java.
Ruiz: Actually, Marc is telling us some bytecode changed indeed, they had to do some adjustment for JaCoCo to support Kotlin 1.5. There is something that changed already.
Lee: I have some tests that are failing because a method that I should have overwritten as part of my bytecode stuff wasn't for whatever reason, so I'm going to have to dig into that and just see what's going on.
Ruiz: From people moving from Java to Kotlin, any advice on how to avoid bad practices from the Java world, example, handling nulls?
Lee: How to avoid them? I mentioned this project that I switched over in 2015. It's a large-ish project. It's an IRC bot, so no money was riding on this particular conversion. IntelliJ IDEA has an option, you can go in and say convert this Java class to Kotlin, and it will just blast it out for you automatically. It gets you like 98% of the way there. What I found was there's a whole lot of places in there where I was exposed to a null pointer exception, because I wasn't checking for it. I had to go back and fix all those. I would start with, you put a question mark on a type that can be null, or a question mark on the type for a field that can be null. I would start without those. In that way, you're essentially telling the compiler, nothing in my application can be null. Your code will break. It won't compile or whatever. You'll start to see those places where a null may or may not creep in. Then you can evaluate those situations. You're like, no, actually, I never want a null there, so let's leave the question mark off. There's someplace that is perfectly valid, so you can put a question mark in. You can start to backfill in some of the nullability. That's probably simpler than just marking everything as nullable, because then everywhere you use any of those fields, there are certain things you have to do. There's a number of different ways you can check for null. It's more work to go and add those everywhere than it is to just figure out where do we really want to allow nulls, and then fix those places. Because, generally, we don't want nulls.
Ruiz: Why Kotlin and the leads that you show will not be the new Groovy plus Grails, what's the big difference for you?
Lee: What's to stop Kotlin from becoming Groovy, essentially? Grails is basically Rails but with Groovy. I think there's a couple differences. Groovy never really had much backing, corporately speaking. I have a lot of friends that are very into Groovy, so I have to be delicate in how I talk about it, because I have stuck my foot in my mouth a few times. It never had much corporate backing. It never had a whole lot of developer buy-in. People who did use it were very passionate about it, and they loved it. I think one of the thing that turned me off about Groovy personally was it was a dynamically typed language, which I've never liked. I've been doing Java since 1996, since there was a Java basically. Being able to reason about types and validate things, that was like very important to me, and Groovy broke that contract. Even though the other language had some nice features, it was harder to reason about. Kotlin is not that. It does a lot of type inference, which I think is amazing. Also, the types are fixed and they're known. That's a big difference between Kotlin and Ruby. Also, Google is all in on Kotlin. It's the preferred recommended language for Android, for example. I think it's going to be around for a while, for that, if no other reason. Kotlin has a lot more corporate backing than Groovy did.
Ruiz: That's true. IntelliJ, yes, it is investing a lot.
Just curious if there is anything with a more idiomatic Kotlin API.
Lee: Idiomatic for what, in what context?
Ruiz: What's the use case for Kotlin? What are the pros and cons? Where does Kotlin shine, amazingly?
Lee: Where does it shine? For me, one of the bigger things is, I think the syntax is a lot sleeker. Java has come on quite a ways. I think the value add for Kotlin is somewhat less now than it used to be. Certainly, like in the Java 6 days when Kotlin was really starting to rise to prominence, you could do all these amazing modern lambdas, and type inferences, and all those sorts of thing on a Java 6 JVM. Which was still 40 years before Java actually adopted some of those features. It's I think why it took off on Android, it really gave a modern language on an older JVM. That's changed a little bit. I still think the syntax is sleeker. When you talk about Java's concepts versus Kotlin, I think the syntax is nicer in Kotlin for that. There are certainly more functions available to you to process your data stream. There's that.
Kotlin has coroutines, which is an implementation of what's called structured concurrency, which I only know because I've been reading about Kotlin coroutines. It doesn't mean a whole lot to me otherwise, but for the CS nerds out there. It basically lets you write concurrent code, like it's imperative. C# has its async, await. There's like all these reactive APIs where you subscribe to this, and on callback this. You can get concurrent code with reactive messaging, or asynchronous code with reactive whatever, but it's a massive buy-in to a really awkward, terrible API. With Kotlin coroutines, for example, you have to launch it in a certain way, because it needs a certain context. Then you just write your code, foo this, bar that, and the Kotlin compiler will actually build in all the stuff necessary to say, fire off this request off in a thread somewhere. You take care of that, I'm going to go work on this, and I will come back ready. Your code just looks like normal imperative code, but it's actually highly scalable, like millions of coroutines running on a single machine. As opposed to Java threads, once you get past certainly 100,000 threads and you will turn your laptop into slug. Coroutines are great.
Project Loom is coming up, and so that will be an interesting competitor to coroutines. It's not going to be in Java 17, it might be in 18. I don't know when it's going to land. It'll be years before that becomes a common thing in the Java world, unless it's so compelling that everyone immediately says we should upgrade to Java 19 today, which would be amazing. I'd love it. Java updates typically has lagged quite a bit.
Ruiz: After Java 17 LTS is out, what features are still lacking that you like in Kotlin? New features in Java, for instance in Project Loom and Virtual Threads, could this close the gap in functionality between languages and keep Kotlin? They are thinking like, Java, it's picking up.
Lee: I think once Loom lands, it gets really interesting. Virtual Threads will be interesting. I'm old enough to remember Green Threads back in the early JVM days. It feels like we're veering back into that era again, although I think it's slightly different than the original Green Threads. Certainly that gap is closing, I think. The nice thing still with Kotlin is they've been able to push the boundaries for what you can do in the JVM without requiring JVM updates. Some of the stuff that's coming in Java necessitates updates to this VM itself, which is fine, which is great. It's a slower process. I think Kotlin will probably still outpace Java, in that respect. At some point, as much as I love Kotlin, and I absolutely love Java as well, I think the value proposition for, "Rewrite your entire application in Kotlin," becomes less at some point, because the gap will be smaller for things that most people care about.
Ruiz: Do you have any advice for developers either in Java or in C#, moving to Kotlin?
Lee: Some of it is just stock advice, but we'll see if something interesting comes out of it. One of the things that I've always learned or heard for years now, is the JVM is so great, because there's literally hundreds of languages that run on the JVM. Everyone was like, if you want a new language, write your test in it first. You're not necessarily betting the company on a test. You kind of are, but it's a little bit more indirect. If your test doesn't work, then suddenly you've just cost the company a billion dollars. You can start with writing small tests, for example, and just get a feel for the language. It can be pretty bite sized. Setting up multi-language projects is not difficult. If you go to the Kotlin website, there's instructions for both Maven and Gradle, depending on what your preference is. The Kotlin world seems to favor Gradle. I think that's driven more by Android than anything else, because Android builds on Gradle, and not Maven. I would start there and just start writing some tests.
What I've actually done, because building Quarkus can be complicated, there's almost 900 modules inside Quarkus [inaudible 00:36:06] to help aid in my development. I originally had Bash scripts, which was fine, because I'm a Linux nerd for decades now. I actually went back and rewrote all those Bash scripts using Kotlin and Quarkus CLI. It's what I work on, so I thought, I might try this out. I wrote all these dev scripts in Kotlin, so they're all running on a JVM. They run so fast, it's like running a Bash script. I never noticed the difference. You can write fairly complex scripts that way in Kotlin, and then run them. Then you really are outside risking the actual product whatever your development scripts might happen to be. Rewrite them in Kotlin and see how it feels. Some things are going to be more awkward, because interacting with the OS from the JVM, execing things out is not so great. You can play with the language, at least in a way that doesn't threaten anything.
See more presentations with transcripts