This article was originally posted on Medium on October 2017
On January 2017 Pivotal introduced Spring framework integration with Kotlin language. Spring is the most popular Java framework, so you could understand my excitement. One of the main drawbacks of Java is the amount of boilerplate code you need to write (or generate, if you’re lucky). Kotlin comes to solve that. So, combining Spring with Kotlin sounded like a terrific idea.
What we’ll do is create an application that manages cats for one cat cafe or another.
You can start with start.spring.io and generated a new Kotlin based web project, or, if you’re using IntelliJ, just choose Spring Initializr and Kotlin+Gradle option.
Initializing your Kotlin application with SpringBoot is neater in all but one aspect:
You still need to pass Java class to run() method. Notice how spread operator is used to convert Array into varargs
I decided to put it in a separate file, although Kotlin is a lot less strict about that than Java. I could have left it in the same Application.kt
Let’s see what our cat looks like:
No, that’s not what I meant!
What’s nice is that you also receive defaults and null-safety out of the box.
Note how we can nest enums within classes, and still use them as default values withing the same class.
Now to the controller:
The controller will return JSON and hold all the cats in memory.
This will respond to GET request and return all know cats as JSON array. A bit shorter than Java version, but nothing major.
Here we start to feel Kotlin a bit more. After generating UUID we assign it both to the cat and to the map that holds them. Using let allows us to limit the scope of id variable.
@RequestBody tells Spring to automatically unmarshal POST body into the Cat object.
The most interesting part is finding a specific cat:
This will get ID from the path, return a cat if it exists in our map, and in case it doesn’t, Elvis operator
?: will throw an exception.
Just throwing an exception doesn’t help us much, since we would like to map it to a proper HTTP code:
This will do.
Up until now I counted ~40 lines of code. I think that’s a really good result for a typesafe language. But no project is complete without tests. Let’s see how Kotlin and SpringBoot fare there.
First, we’ll need an object, that would represent a list of cats.
That’s a nice trick Kotlin provides to avoid JVM type erasure. From now on, in our tests CatsList is ArrayList , and could be used as such.
@RunWith tells Spring to inject dependencies. Setting webEnvironment specifically provides us with TestRestTemplate. For those who like it, Spring also supports more fluent syntax, but I personally like my tests imperative. Makes them easier to debug.
In our next test we create our first cat. Note that not all arguments are supplied to the constructor, making use of default values. And since they’re supplied by name, arguments order doesn’t matter.
Since Cat also contains a random UUID, we use
isEqualToComparingOnlyGivenFields . That’s a mouthful, but it allows us to compare only the interesting members of the object, ignoring others. Also note that body is already a list of cats. We can use square brackets and not casting is needed.
You can see that our newly created CatsLists allows us to preserve generics.
Next we’ll test getting a specific cat:
Note how we use string interpolation with
The last test would be to check that if ID is incorrect, we receive a proper 404 response.
Again, we use string interpolation. We also don’t want Spring to parse the response, since we expect it to be empty, so we use
Any class to indicate that.
How long does it take to start such application?
Started ApplicationKt in 1.972 seconds (JVM running for 2.236)
Yep, that’s Spring application starting in under two seconds. I think that startup time actually beats even some Go projects I’ve seen, not to mention other languages. And we have type safe, fully tested CRUD application in ~100 lines of code, give or take. Half of which are tests.
I think that both Pivotal and JetBrains did an amazing job there, making developing on JVM great again. Hope they’ll get rid of
If you want to play with this project, you can grab it from here: