Kotlin WebApp Tutorial — ToDoList — Part 3

Using SpringBoot instead of SparkJava for the Web Framework

Wayne Ellis
4 min readSep 17, 2017

A few weeks back, I wrote a two-part series on creating a Web App using Kotlin. For it, I decided to use SparkJava to serve the REST endpoints, and VueJS for the front end. One of the main questions I have had since is, why SparkJava and not SpringBoot? Well, I believe it is a matter of preference, but both a valid and capable options…but for completeness, I decided to write a quick implementation using SpringBoot.

Jumping Straight In

I am not going to go back over, the concepts that were covered in Part 1, or Part 2, you can welcome to click back and read. All I am going to do in this part is to replace what we did in Part 1 and build our REST endpoints in SpringBoot.

To get us up and running far quicker, I suggest you just go to http://start.spring.io. and choose to genereate a Maven project, with Kotlin and I chose SpringBoot 2. Set the group and artefact of your choice (I did group=codemwnci, artefact=kotlinspringboot). From the dependencies, choose Web, JPA and H2.

The code

So, lets go and explain this code.

First off, we’ll start with lines 38–43. This is the Todo object. This was a single line on the previous implementation, but I have split it out for clarity, because we have a few annotations on the id field. It is marked as an Entity so that JPA can pick this up, and then the Id andGeneratedValue elements are set to tell the database that this is an auto-increment value. You will also notice that all the values have been given default values; this is because JPA needs a no-args constructor, so giving all elements a default value achieves this in the background.

Note: we haven’t needed to set up a datasource, or the H2 database. All of this is done for us, by the H2 dependency that we pulled in at the start.

Next, the JPA Repository allows us to use DB helper methods to access our underlying database entities (we will use FindAll, FindById, Save, and DeleteById). In Kotlin, all we need to do is implement the interface (line 36), to extend the JpaRepository, setting the Type as Todo, and Key as a Long.

The final part is the RestController, which accesses the DB and works with the entities.

  • Line 8: This sets up the class as Controller, serving REST requests, with all mappings inside the class being served up from the /todo path.
  • Line 9: The class is defined here, with the main thing of note is that the JPARepository is passed in. This achieves the dependency injection required to give us an implementation of our TodoRepository interface.
  • Line 11/12: This returns a JSON respoonse of all the Todos in the database. As we are working with a RestController, if the response is a class, it is converted into JSON. This endpoint has been defined in a functional style (no parenthesise or return type, just an equals sign).
  • Line 14/15: This function returns a single Todo. The Id is defined as a path variable using the {id} syntax in the GetMapping value, which is then passed in as a parameter into the function. We can then once again is the jpaRepository to return a Todo using the findById function.
  • Line 17/18: This function is similar to the previous two, except it is a PostMapping (not Get), and the data is taken from the RequestBody, rathen than a PathVariable. We then use the JPA Repository to save a newly created Todo object, which we create using a named parameter (we only pass in a single parameter, all the others are defaulted). Note that the Id set to default of zero will be ignored by the DB in favour of the auto-generated Id.
  • Line 20–26: This function is slightly different as we are not using the functional style (there is too much going on), which means we need a return type and a return statement. Similar to Line 14, we have the {id} passed into the parameter list, along with a Todo object, which is automatically converted from the JSON passed in from the RequestBody. The code then goes onto load the Todo from the Database (using the findById function), update the text and done variables, and then return the saved entity.
  • Line 28–32: This function simply takes the {id} from the path and calls the deleteById function, and finally responds with the sameOk text that we returned in the SparkJava implementation.

And that is it. Slightly less verbose than the SparkJava implementation, due to the additional magic delivered to us by SpringBoot and the SpringBoot dependencies.

SpringBoot or SparkJava?

As I said at the start of this article, I think it is a preference, based on your own style and your own requirements. I personally prefer the expressive nature of the routes in SparkJava, over the annotations in Spring, but it is a very minor point, because Spring still looks very clean.

I didn’t have to set up anything for the DB (like Hikari or Kotliquery), which is fine for a simple implementation likes this, but for a bigger, or more Enterprise implementation, I know many would prefer to have the control in favour of a small amount of verbosity.

JPA also took away a lot of the verbosity of dealing with the entities. Again, in many situations this is fantastic…however, there are cases where loading the whole entity to make a minor change is overkill. I read an argument a few years back that stated that DBs did not need a DSL like JPA offers when you have a perfectly good one in SQL. In my experience, I prefer to work directly with the DB, especially with DTOs so easy to create in Kotlin, but it really is a personal choice.

I’d be interested to hear your own preferences and opinions.

--

--

Wayne Ellis

Software Architect; Author of Introducing the Play Framework; Technologist.