More posts by Intelliware Development

On an effort to leverage Kotlin for our projects, earlier this year we had a study group with the goal to learn more about this development language, that’s receiving increasing attention and adoption in the industry. The study group was in partnership with one of our clients, which is already using Kotlin on their projects, and the interest it created among my Intelliware colleges motivated me to create a Kotlin lab, showing how to create a Kotlin Spring Boot app. The lab has the advantage of a more condensed format, compared to a study group, able to give the participants the opportunity to create an application from scratch in a little bit more than an hour, without any previous knowledge of the language.

I created this post with the lab content with the hope that it can be useful to a bigger audience, be it a developer trying to learn Kotlin by himself or a group willing to go through the lab together. The content is inspired by Spring Boot Kotlin Tutorial, with some of its content adapted to a lab format and specific “understanding the code” sections helping the participant understand the language concepts used.

STEP 1: Install IntelliJ

Kotlin is a language developed by JetBrains, the company behind IntelliJ, so even though you can use any text editor, IntelliJ is recommended due to better integration with the language.

Click here to download and install the Ultimate or Community edition of IntelliJ.

 

Step 2: Bootstrap your application

  1. Go to Spring Initializr
  2. Select Kotlin as a language
  3. Use “blog” for Artifact
  4. For dependencies, select: Web, JPA, and H2

Download Screen

5. Click on Generate Project

6. Unpack the downloaded project

7. On command line run the application with ./mvnw spring-boot:run

 

Step 3: Import the project on IntelliJ

  1. File -> new -> Project from existing sources
  2. Select the project folder
  3. Chose “Import project from external model” -> Maven
  4. Follow the next screens and Finish

 

Step 4: Look at the application bootstrapped

  1. Open the file com.example.blog.BlogApplication. There are a few things you will notice:
    • Lack of semicolons
    • Since the class has no body, the curly braces can be omitted
    • The main function is a top-level function, meaning there’s no need to create a class to hold it, like languages such as Java, C# or Scala
    • The default visibility is public, which can be omitted for the main function
    • If you navigate to the declaration of runApplication, you’ll see that it’s declared in a Kotlin extension class. It’s part of the Spring Boot Kotlin support, enabling writing more idiomatic code
  2. Open the pom.xml file. There are a few things you will notice:
    • kotlin-maven-plugin: used to compile Kotlin code. sourceDirectory and testSourceDirectory are also configured
    • kotlin-maven-allopen: Kotlin has classes and their members final by default, which makes it inconvenient to use frameworks such as Spring that require classes to be open. The all-open plugin, which has Spring support, makes classes annotated with a specific annotation and their members open without the explicit open keyword.

 

Step 5: Create the first Rest Resource

  1. Implement the class HelloWorldResource
  2. Re-run the application with ./mvnw spring-boot:run
  3. Open your browser on http://localhost:8080/hello. You should see “Hello” on the page displayed.

Understanding the code

  • hello() is a single-expression function, so the curly braces can be omitted
  • For single-expression functions, explicitly declaring the return type is optional when this can be inferred by the compile.

 

Step 6: Create the Article model and Resources

  1. Implement the Article class with the properties title and content
  2. Implement the ArticleResource Rest endpoint returning a list of Articles.
  3. Re-run the application with ./mvnw spring-boot:run
  4. Open your browser on http://localhost:8080/article. You should see the JSON representation of the list returned

Understanding the code

  • Article
    • Is a class whose main purpose is to hold data, making it a good candidate to be a Data Class, which automatically provide equals()hashCode()toString()componentN() and copy() functions
    • It uses its primary constructor to declare and initialize its properties in a concise way. Properties declared in the primary constructor can be mutable (var) or read-only (val)
  • ArticleResource
    • To create instances of the Article class, we call the constructor as if it was a regular function
    • Kotlin does not have a new keyword
    • listOffunction is part of Kotlin Standard Library, which provides living essentials for everyday work with Kotlin
    • You didn’t have to import listOf. Just like Java has java.lang, Kotlin has some packages that are imported by default.

 

Step 7: Add Article properties with default values

  1. Add the properties createdAt of type LocalDateTime and id of type Long? with default values
  2. Re-run the application with ./mvnw spring-boot:run
  3. Open your browser on http://localhost:8080/article. You should see the new properties on the objects in the list

Understanding the code

  • Function arguments can have default values, which are used when a corresponding argument is omitted
  • Kotlin’s type system is aimed at eliminating the danger of null references from code. Since the Article.id is only specified when it’s persisted (to be implemented in a following section), its supposed to allow null, so the nullable Long? is used
  • Since we are satisfied with the default values of the new parameters, we do not need to change the Articleinstantiation on Articleget.getArticles()

 

Step 8: Test with JUnit 5

While JUnit 4 is still the default testing framework provided with Spring Boot, and can be used with Kotlin, JUnit 5 provides features handy with Kotlin, including autowiring of constructor / method parameters which allows to use non-nullable valproperties and the possibility to use @BeforeAll/@AfterAll on regular non-static methods. Follow the steps below, or, to make it easier, see the necessary changes in this diff or the expected final file content: pom.xml and BlogApplicationTests.kt

  1. Exclude junit Maven transitive dependency from spring-boot-starter-test
  2. Add junit-jupiter-engine Maven dependency
  3. Add junit-platform-surefire-provider Maven dependency to maven-surefire-plugin
  4. Refactor BlogApplicationTests.kt to Junit 5
  5. Run ./mvnw clean install and check if the build is still successful

 

STEP 9: Add test to ArticleResource

  1. Implement the ArticleResourceTest. Make sure to put it in the src/test/kotlin/com/example/blog/ folder. This short test is enough for the purpose of this lab, but I hope in real life you test more than the result size
  2. Run ./mvnw clean install and check if the test runs and the build is still successful

Understanding the code

  • We’re using SpringExtension which is able to inject dependencies into test constructors. This makes it a good fit with Kotlin immutable and non-nullable properties
  • We use real sentences in test function names. Backticks are part of the language to help with the Java interop but they also help writing more expressive test function names, instead of the usual camel-case naming
  • getForEntity is another Spring Kotlin extension. It takes advantage of Kotlin reified type parameters, overcoming Java type erasure limitation which would require the usage of ParameterizedTypeReference<List<Article>>
  • response.body?.size is a safe way of accessing the nullable body property. It will return size if body is not null, and null otherwise. Other ways are also available, such as if statments and the Elvis operator

 

Step 10: Persistence with JPA

  1. Annotate Article with @Entity and Article.id with @Id @GeneratedValue. Final result: Article
  2. Implement ArticleRepository
  3. Use the ArticleRepository to retrieve the list of Articles on ArticleResource
  4. Add the Kotlin JPA plugin and add kotlin-maven-noarg dependency to the pom.xml`
  5. Re-run the application with ./mvnw spring-boot:run
  6. Open your browser on http://localhost:8080/article. The result is not very exciting and you won’t see anything since the database is empty. We’ll solve this on next section.

Understanding the code

  • JPA annotations can be used in the primary constructors, contributing for a concise code
  • Primary constructors will also have its dependencies automatically autowired, which is the case of ArticleResource
  • JPA requires the entities to have a zero-argument constructor. Since we added the primary constructor to Article, the entity is no longer satisfying that requirement. Kotlin no-arg plugin with JPA support adds a zero-argument constructor for classes annotated with @Entity@Embeddable and @MappedSuperclass

 

Step 11: Add some Articles to the database

  1. Implement the function BlogApplication.initDatabase()
  2. Re-run the application with ./mvnw spring-boot:run
  3. Open your browser on http://localhost:8080/article. Now you should see some Articles on the page

Understanding the code

  • Now that BlogApplication has a body, it needs curly braces
  • The function initDatabase produces a @Bean of type CommandLineRunner which implements a callback to run specific pieces of code when an application is fully started
  • CommandLineRunner is a FunctionalInterface, meaning it’s a Single Abstract Method (SAM) interface, which can be automatically converted from Kotlin function literals. If it got too complicated, the bottom line is the Kotlin support for functional programming allows us to implement the method the way we did, instead of having to explicitly declare a class to implement a single method

So that’s it for now, even though we haven’t implemented the most exciting application, the small portion of code we wrote is a starting point for getting more familiar with Kotlin and how it integrates with Spring Boot. We also saw language features such as, data classes, primary constructors, Kotlin Standard Library, default imports, function parameters, default values, nullable and non-nullable types, reified type parameters, lambda expressions and function literals, JUnit 5 and JPA integration, Kotlin Maven plugins and Spring Kotlin extensions.

The complete source code can be found at kotlin-spring-boot-lab.