Back-end8 minute read

Using Kotlin for Back-end Development: A Quick Overview

Kotlin has features that make it an ideal language for back-end development. Learn what these features are and how you can use them to create high-performing systems.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

Kotlin has features that make it an ideal language for back-end development. Learn what these features are and how you can use them to create high-performing systems.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.
Boldizsar Akos Mezei
Verified Expert in Engineering

Boldizsar is a Java/Scala back-end developer who has worked at Morgan Stanley on a group of microservices.

Read More

Expertise

PREVIOUSLY AT

Morgan Stanley
Share

I do not have to introduce Kotlin to native Android developers, since in May 2017, Google announced that it would be the official language for Android development. Since then, it has gained a lot of traction as being the primary language choice for developing new and shiny Android apps. It solves a lot of pain points of Java, so the new apps are mostly written in it, and the old ones are being rewritten in it.

There is no doubt that it is great on the front-end side of applications, and when you first mention Kotlin, most people associate it with the Android OS. However, in this article, I would talk about Kotlin as a back-end language and I would like to share my story about creating a fast, reliable, and asynchronous Kotlin back end for my Android hobby project. I will not discuss what the project is about, as it is out of the scope of this article; rather, I will focus on explaining why I have chosen Kotlin and why I think it is a great language for writing server-side applications or REST APIs.

Why Kotlin?

Let me go back to the very beginning of my journey. I always had entrepreneurial ambitions, and I thought that the first step on this road is to create something on my own. Nothing huge, nothing world-changing, just something small that I and maybe my family and friends can use. After having a reasonable idea, I jumped right into it and started implementing it. The first thing you do at the beginning of any project is to choose your tools. After all, the right set of tools can save you a lot of time and money in the long run. So this is what I did.

I am primarily a Java developer. I have written several back-end systems and REST APIs using Java and Spring, and I do think that these two are great tools for doing such things. Java on its own is a comprehensive language, but combined with Spring, there is nothing you can’t implement.

However, there is only one tiny hair in the soup. Verbosity. Although Spring and the latest versions of Java help a great deal with that, still you have to handle a lot of boilerplate code. And as once a great guy told me - the safest, most reliable, and bug-free code is the code that is not written down. Take, for example, this trivial Java class:

public class Person {
	private final String name;
	private final int age;
	public Person(String name, int age) {
    	this.name = name;
    	this.age = age;
	}

	public String getName() {
    	return name;
	}
	public int getAge() {
    	return age;
	}
}

In my opinion, this is a lot of code for simply saying, “I want a class with two read-only fields.” The worst part is that the constructor and the methods were autogenerated. Still, when you are reviewing a pull request, you always go through them because, well, you never know if they are what you need or not. Sure, this can be shortened with third-party libraries like Lombok, but wouldn’t it be nice if we could do this out of the box? Let’s see this same exact class in Kotlin:

class Person(
	val name: String,
	val age: Int
)

It’s definitely shorter and simpler. The variables are final as we use the val keyword; the constructor and the getters are generated at compile time. If we prefer not to have an immutable person object, we can simply change val to var, and voila, we have a mutable person, and all we have to do is just change one letter.

My second favorite part in a simple Java POJO class is the overridden equals() and hashCode(). These are again autogenerated most of the time, yet you always have to go over them, just to make sure. Good news is that Kotlin can handle this as well. Simply change your class to a data class, and you get equals() and hashCode() out of the box.

data class Person(
	val name: String,
	val age: Int
)

In short, even though I love Java, I wanted to create a minimum viable product for my project as soon as possible in a short time. And in the case of software development, the simplest way to achieve this is to write less code. Thus, my search for a better language for back-end development continued. With this thought in mind, I first shifted toward Node.js. It has some significant advantages—a few lines and your Express server is up and running, listening on port 8080, and responding with Hello World! each time you send a get request.

let express = require('express')
let app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(8080);

Easy, simple, and fast. Just what you would expect from one of the most popular programming languages out there. I do enjoy working with JavaScript, and for a brief moment, I thought that I had found the right tool, but then I was haunted by the fact that JavaScript is dynamically typed. Don’t get me wrong, I do think that dynamic typing is great on the front end, but in my experience, having a statically typed back end simply gives you extra confidence that your server is less likely to crash at runtime because of type mismatches. And let’s be honest here, when your back end is serving several hundred thousand users, you really don’t want that to happen. Node.js, however, offered one great feature that I wanted to keep, which is being able to easily write asynchronous code and services.

With these requirements in mind, I chose to write my Kotlin Android back end also in Kotlin.

Kotlin: A Quick Overview

For those of you who have never heard of it before, Kotlin is an open-source, statically typed programming language that supports both object-oriented and functional programming. It provides similar syntax and concepts as C#, Java, or Scala and it mainly targets the JVM but also has variants that target JavaScript or native code. It is very similar to Java in that Kotlin/JVM compiles down to Java bytecode, so for those back-end engineers who have a JVM background, Kotlin will be easy to grasp.

As its official page states, the aim of Kotlin is not to be unique but to draw inspiration and best practices from decades of language development. It can be used with any Java IDE or from the command line, but I personally prefer and recommend using it with IntelliJ. It is actively maintained and upgraded by the JetBrains team, and don’t worry about buying the paid version—if you just started off with Kotlin, the community version of IntelliJ will serve your every need. The three most important aspects of Kotlin that I would like to point out are that it is: a) concise (it drastically reduces boilerplate code), b) safe (for one thing, it is built for avoiding null pointer exceptions), and c) interoperable (you can leverage the existing libraries for the JVM, Android, or the browser).

Kotlin Coroutines

Everyone wants to have services that serve users fast. To reach the maximum capacity of your server, the first thing you can do is having a multithreaded application. Java is quite cumbersome with that. When you learn Java, you first learn that if you want a multithreaded application, you should either extend the Thread class or implement the Runnable interface. Beginners never really understand what the difference is (if there is any), but to add to the confusion, they are also told to always start a thread with the run method, never to use the start method. Or wait, was it the other way around? After all, it does not matter, you should not start a thread manually anyway, it is too expensive, rather use a thread pool. Simple, except that it’s not.

Fortunately, Kotlin has an even simpler solution called coroutines. Simply put, coroutines make it possible to write asynchronous, non-blocking code in a very fluent way. The core idea is having functions that can be suspended; in other words, the computation can be suspended at some point and resumed later on. The best part is that when writing non-blocking code, the programming model does not really change so writing non-blocking code is essentially the same as writing blocking code. Let’s see two examples:

fun sendRequest(): Int {
   /* do some heavy work */
   return 1;
}

This example shows a blocking function. The thread executing this code snippet will not do any other work until the function returns, which in case of an API or database call could be a couple of seconds. We really don’t want to block our thread while waiting for another service so let’s turn this function into a non-blocking one.

suspend fun sendRequest(): Int {
   /* do some heavy work */
   return 1;
}

This example shows how we can turn our method into a non-blocking function that is able to be suspended. This means that if, for simplicity, the heavy work is a simple delay() function call of 10 seconds, the executing thread will keep working on other tasks for that time and it will resume the execution of the function after the 10 seconds pass. Nice, non-blocking code achieved with one keyword.

Asynchronous Service with Ktor

When it comes to writing REST APIs, there are some extra steps one must take, like starting an embedded server or parsing the request, and of course, no one wants to do it manually. Java has Spring Boot, which makes things really easy, and luckily, Kotlin has a framework called Ktor. Ktor is a web framework for building asynchronous servers. As its website states, Ktor is “easy to use, fun, and asynchronous.” Now, fun is subjective, so I would not like to prove that, however, let’s see a snippet that proves easy to use and asynchronous.

fun main() {
	embeddedServer(Tomcat, 8080) {
    	routing {
        	get {
            	call.respond("Hello world!")
        	}
    	}
	}.start(wait = true)
}

The example above presents a fully functional Kotlin Ktor server that is running on an embedded Tomcat server, listens on port 8080, and will respond asynchronously with “Hello world!” to get requests. All this in less than 10 lines of code.

Ktor can obviously do much more than this. Presenting all the features of Ktor requires its own article, but among many things, it makes login and authentication easy as pie. Read more about what Ktor can do on the server side and how to configure it here.

Other Benefits of Kotlin on the Back End

The first benefit I would like to point out is that you can use Java libraries in Kotlin, and trust me, there are a lot of amazing third-party libraries for Java that can make your life easier. Why would you write your own implementation when there is an open-source, ready-to-use library that does the job perfectly? Using these with Kotlin works flawlessly.

Another major advantage of Kotlin and Ktor is the extensive testing libraries and frameworks you can use. The Junit framework works like a charm with Kotlin, and Ktor adds on top of this its own testing library that allows you to write end-to-end tests and integration tests in no time. You can use a custom test engine that will run your entire application and can handle requests just like the live application would do.

Conclusion

As I mentioned earlier, I am primarily a Java back-end developer having several server-side applications and REST APIs behind me. Although I love programming in Java, I think that there is no single best language or framework that is perfect for any job and can solve any problem. My approach is to get familiar with as many tools as you can, and when a problem comes, choose the best tool that can solve that particular problem flawlessly.

As the Kotlin site states, the aim of Kotlin is not to be unique; instead, it draws inspiration and best practices from decades of language development, and I do believe that when it comes to back-end development, Kotlin, Coroutines, and Ktor make an amazing trio to do the job. You can read more about Kotlin and its usefulness as a programming language here.

Further Reading on the Toptal Blog:

Understanding the basics

  • Are coroutines asynchronous?

    Yes. Coroutines are threads that operate asynchronously and are suspended if necessary, then restarted later. They can be used to achieve a high level of performance on the back end.

  • Is Kotlin a back-end language?

    While there are few programming languages that can be classified as strictly front-end or back-end, Kotlin has characteristics such as static typing that make it easy to use for back-end programming.

  • Is Kotlin good for the back end?

    Thanks to high-performance features like coroutines and the ability to make use of Java libraries, Kotlin makes an excellent language for back-end development.

  • Are coroutines threads?

    Yes. Coroutines are threads that are runnable and suspendable. They help applications manage multiple user activities simultaneously.

Hire a Toptal expert on this topic.
Hire Now
Boldizsar Akos Mezei

Boldizsar Akos Mezei

Verified Expert in Engineering

Budapest, Hungary

Member since March 17, 2020

About the author

Boldizsar is a Java/Scala back-end developer who has worked at Morgan Stanley on a group of microservices.

Read More
authors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

Expertise

PREVIOUSLY AT

Morgan Stanley

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

Join the Toptal® community.