---
title: "Kotlin: Like Java, But Better (Part 2)"
description: "If you haven't already read part one of this blog series, then check out '\nKotlin: Like Java, But Better Part 1\n[https://blog.ippon.tech/kotlin-like-java-but-better-part-1/]' to learn about Kotlin's\nbackground and features!\n\nIntroduction\nOne of Kotlin's greatest strengths is the full interoperability with Java. This\nenables developers"
image: https://blog.ippon.tech/hubfs/Imported_Blog_Media/Kotlin-Like-Java-But-Better-Jan-18-2024-06-07-29-2128-PM.png
---

[Skip to main content](https://blog.ippon.tech/kotlin-like-java-but-better-part-2#main)

[![IpponLogoKleinBlue](https://blog.ippon.tech/hs-fs/hubfs/IpponLogoKleinBlue.png?width=219&height=64&name=IpponLogoKleinBlue.png) ![IpponLogoKleinBlue](https://blog.ippon.tech/hs-fs/hubfs/IpponLogoKleinBlue.png?width=219&height=64&name=IpponLogoKleinBlue.png) ![IpponLogoKleinBlue](https://blog.ippon.tech/hs-fs/hubfs/IpponLogoKleinBlue.png?width=168&height=49&name=IpponLogoKleinBlue.png) ![IpponLogoKleinBlue](https://blog.ippon.tech/hs-fs/hubfs/IpponLogoKleinBlue.png?width=168&height=49&name=IpponLogoKleinBlue.png)](https://ipponusa.com/)

- [Home](https://ipponusa.com)
- [Show submenu for About About](https://ipponusa.com/about-us) 
    - [Who We Are](https://ipponusa.com/who-we-are)
    - [Careers](https://ipponusa.com/careers)
    - [Show submenu for Our Partners Our Partners](https://ipponusa.com/our-partners/) 
          - [AWS](https://ipponusa.com/our-partners/aws/)
          - [Snowflake](https://ipponusa.com/our-partners/snowflake/)
          - [Databricks](https://ipponusa.com/our-partners/databricks/)
          - [Microsoft](https://ipponusa.com/our-partners/microsoft/)
- [Show submenu for Services Services](https://ipponusa.com/services) 
    - [Snowflake](https://ipponusa.com/service/snowflake-concierge/)
    - [Artificial Intelligence](https://ipponusa.com/service/artificial-intelligence/)
    - [Data & Analytics](https://ipponusa.com/service/data-analytics/)
    - [Cloud Strategy](https://ipponusa.com/service/cloud-strategy/)
    - [Platform Modernization](https://ipponusa.com/service/platform-moderization/)
    - [Product Innovation](https://ipponusa.com/service/product-innovation/)
    - [Operating Model](https://ipponusa.com/service/operating-model/)
- [Blogs](https://blog.ippon.tech/)
- [Success Stories](https://ipponusa.com/success-stories/)
- [Show submenu for Resources Resources](https://ipponusa.com/resources/) 
    - [eBooks](https://ipponusa.com/ebooks/)
    - [The Data Pour](https://info.ippon.tech/the-data-pour)
    - [Videos & Webinars](https://info.ippon.tech/videos-and-webinars)
    - [Media Center](https://ipponusa.com/media-center/)

Search

Open main navigation

Close main navigation

- [Home](https://ipponusa.com)
- Show submenu for About About 
  
    - About
    - [About](https://ipponusa.com/about-us)
    - [Who We Are](https://ipponusa.com/who-we-are)
    - [Careers](https://ipponusa.com/careers)
    - Show submenu for Our Partners Our Partners 
      
          - Our Partners
          - [Our Partners](https://ipponusa.com/our-partners/)
          - [AWS](https://ipponusa.com/our-partners/aws/)
          - [Snowflake](https://ipponusa.com/our-partners/snowflake/)
          - [Databricks](https://ipponusa.com/our-partners/databricks/)
          - [Microsoft](https://ipponusa.com/our-partners/microsoft/)
- Show submenu for Services Services 
  
    - Services
    - [Services](https://ipponusa.com/services)
    - [Snowflake](https://ipponusa.com/service/snowflake-concierge/)
    - [Artificial Intelligence](https://ipponusa.com/service/artificial-intelligence/)
    - [Data & Analytics](https://ipponusa.com/service/data-analytics/)
    - [Cloud Strategy](https://ipponusa.com/service/cloud-strategy/)
    - [Platform Modernization](https://ipponusa.com/service/platform-moderization/)
    - [Product Innovation](https://ipponusa.com/service/product-innovation/)
    - [Operating Model](https://ipponusa.com/service/operating-model/)
- [Blogs](https://blog.ippon.tech/)
- [Success Stories](https://ipponusa.com/success-stories/)
- Show submenu for Resources Resources 
  
    - Resources
    - [Resources](https://ipponusa.com/resources/)
    - [eBooks](https://ipponusa.com/ebooks/)
    - [The Data Pour](https://info.ippon.tech/the-data-pour)
    - [Videos & Webinars](https://info.ippon.tech/videos-and-webinars)
    - [Media Center](https://ipponusa.com/media-center/)
- Search
- [Contact Us](https://ipponusa.com/contact/)

[Contact Us](https://ipponusa.com/contact/)

# Kotlin: Like Java, But Better (Part 2)

![Davis Mohar](https://app.hubspot.com/settings/avatar/d41d8cd98f00b204e9800998ecf8427e)

 by [Davis Mohar](https://blog.ippon.tech/author/davis-mohar)

June 17, 2021

![Kotlin: Like Java, But Better (Part 2)](https://blog.ippon.tech/hubfs/Imported_Blog_Media/Kotlin-Like-Java-But-Better-Jan-18-2024-06-07-29-2128-PM.png)

[Java](https://blog.ippon.tech/tag/java/) [Spring Boot](https://blog.ippon.tech/tag/spring-boot/) [Kotlin](https://blog.ippon.tech/tag/kotlin/)

 

If you haven't already read part one of this blog series, then check out '[Kotlin: Like Java, But Better Part 1](https://blog.ippon.tech/kotlin-like-java-but-better-part-1/)' to learn about Kotlin's background and features!

## Introduction

One of Kotlin's greatest strengths is the full interoperability with Java. This enables developers to write Kotlin code in existing Java projects, which makes it much easier to get started with Kotlin. In this blog post, we will put this interoperability to the test by converting an existing Java Spring Boot microservice into Kotlin. We will assume the reader's familiarity with Java and Spring Boot for this exercise.

If you're following along at home, you can clone the [source code from github](https://github.com/davismohar/kotlin-spring-boot-demo?ref=blog.ippon.tech). The 'main' branch has the starting Java code, and the 'kotlin' branch contains the final app that has been converted to Kotlin.

It is highly recommended to use [IntelliJ IDEA](https://www.jetbrains.com/idea/?ref=blog.ippon.tech) as your IDE when working with Kotlin files.

## Our Microservice

First, lets take a tour of the Spring application we will be working with. This is a basic app that has a few REST endpoints that allow us to manipulate a list of people. The endpoints are:

- `/api/ping` 
    - Basic health check endpoint. Can be used to verify the application is up.
- `/api/people/add` 
    - Make a `POST` request to this endpoint with a Person object in the body to add that Person to the list.
    - A valid Person JSON Object looks like: `{"firstName":"Jane", "lastName": "Doe", "Age": 31}`
- `/api/people` 
    - A `GET` request to this endpoint will return the current list of people.

### /api/ping

Start up the app in IntelliJ (or with `mvn spring-boot:run`) and test these endpoints out. First, we can hit the `/ping` endpoint to double check that our service is running and accepting connections. We expect a simple `pong` response from this request.

```
curl --request GET --url http://localhost:8080/api/ping
```

### /api/people/add

We can then add a new person to the service using the `/people/add` endpoint. You can run this command several times to add multiple people to our service. We expect the first and last name of the person we added to be returned.

```
curl --request POST \
  --url http://localhost:8080/api/people/add \
  --header 'Content-Type: application/json' \
  --data '{
	"firstName": "Jane",
	"lastName": "Doe",
	"age": 32
}'
```

The expected response looks like:

```
Jane Doe
```

### /api/people

Finally, we can request the list of people with the `/people` endpoint.

```
curl --request GET \
  --url http://localhost:8080/api/people
```

We expect a response that looks something like this (assuming you've added two People so far):

```
[
  {
    "firstName": "Jane",
    "lastName": "Doe",
    "age": 32
  },
  {
    "firstName": "John",
    "lastName": "Doe",
    "age": 34
  }
]
```

As we continue working with the service, you may want to use a tool like [Postman](https://www.postman.com/?ref=blog.ippon.tech) or [Insomnia](https://insomnia.rest/?ref=blog.ippon.tech) instead of manually editing the curl commands.

## Diving Into the Code

Now that we have explored the general behavior of the application, let's take a look at the `Person.java`, `PersonService.java`, and `PersonController.java` classes and convert them to Kotlin classes.

There is also a test suite included with this repo that we will be using to ensure that the behavior and functionality of the application does not change as we convert our application.

## The `Person` Class

### Person.java

```
public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(
            @JsonProperty("firstName") String firstName,
            @JsonProperty("lastName") String lastName,
            @JsonProperty("age") int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    public String getFirstName() {
        return this.firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public int getAge() {
        return this.age;
    }

    public void setFirstName(String name) {
        this.firstName = name;
    }

    public void setLastName(String name) {
        this.lastName = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return this.firstName + " " + this.lastName;
    }
}
```

This class represents the Person model that our service works with. This is a fairly basic Plain Old Java Object (POJO) that includes several boilerplate getter and setter functions, as well as `@JsonProperty` annotations to assist in JSON Serialization. As we are rewriting this class in Kotlin, this is a great opportunity to utilize [Data Classes](https://kotlinlang.org/docs/data-classes.html?ref=blog.ippon.tech), which already have default getter and setter functions, as well as defaults for other common functions such as `toString()`. We can delete the old Person.Java file, and create a new Person.kt Kotlin file that looks like this:

### Person.kt

```
/** * Class constructor declaration, which declares the properties for the class, * as well as getters and setters for these properties. **/
data class Person(
    @JsonProperty("firstName") var firstName : String,
    @JsonProperty("lastName") var lastName: String,
    @JsonProperty("age") var age: Int
) {
    /** * Override of the default toString() function to match the functionality * of the Java class. Notice the use of string templates to dynamically * insert the variables into the string **/
    override fun toString(): String {
        return "$firstName $lastName"
    }
}
```

We can verify that our application functionality hasn't changed by running our test suite with a `mvn test`. Once we're sure that our code is still working as expected, we can move on to converting our next class.

## The `PersonService` Class

### PersonService.java

```
@Service
public class PersonService {
    private ArrayList<Person> people;

    public JavaPersonService() {
        people = new ArrayList<>();
    }

    public ArrayList<Person> getPeople() {
        return this.people;
    }

    public Person addPerson(Person person) {
        this.people.add(person);
        return person;
    }
}
```

The PersonService handles the logic for maintaining our Person list. There's nothing too complicated going on with this class, but take note that it has the Spring `@Service` annotation. We will want to make sure to include that in our Kotlin class, as well as double check that it functions the same way once we have made our conversion.

As we're writing the Kotlin code, we can initialize our `people` variable with the declaration so that there is no need to write an `init` block to replace the constructor. We also don't need to include the `getPeople()` function, as that is automatically provided for us. The only function that we need to rewrite is the `addPerson()` function. This function in our Kotlin code is nearly identical, save for minor syntactic differences. Notice we have the same `@Service` annotation above the class as well. Spring requires no additional information or configuration to support the Java/Kotlin interoperability.

### PersonService.kt

```
@Service
class PersonService {
    // Directly initialize the 'people' ArrayList
    val people = ArrayList<Person>()
 
    fun addPerson(person: Person): Person {
        people.add(person)
        return person
    }
}
```

Once again, we can run a `mvn test` to verify that our functionality hasn't changed. Let's move on to our third and final class to convert.

## The `PersonController` class

### PersonController.java

```
@Controller
@RequestMapping("/api")
public class PersonController {

    PersonService personService = new PersonService();

    @GetMapping("/ping")
    public ResponseEntity<String> ping() {
        return new ResponseEntity<>("pong", HttpStatus.OK);
    }

    @GetMapping("/people")
    @ResponseBody
    public  ResponseEntity<ArrayList<Person>> getPeople() {
        return new ResponseEntity<>(personService.getPeople(), HttpStatus.OK);
    }

     @PostMapping("/people/add")
    fun addPerson(
        @RequestBody person: Person
    ): ResponseEntity<String> {
        return ResponseEntity(personService.addPerson(person).toString(), HttpStatus.OK)
    }
}
```

Our controller class is fairly basic, without very much we can change or improve as we convert to Kotlin. Notice that in our Kotlin Controller the `person` argument in the `addPerson()` function is not nullable. This is intentional, as Spring will automatically respond with a `400 Bad Request` if a Person object is not passed in the body of the request, so we can always assume that the body request exists. We have also made no changes to any of the Spring annotations, further showcasing the interoperability support that is offered by Spring.

### PersonController.kt

```
@Controller
@RequestMapping("/api")
class PersonController {
    val personService = PersonService()

    @GetMapping("/ping")
    fun ping(): ResponseEntity<String> { return ResponseEntity("pong", HttpStatus.OK) }

    @GetMapping("/people")
    @ResponseBody
    fun getPeople(): ResponseEntity<ArrayList<Person>> {
        return ResponseEntity(personService.people, HttpStatus.OK)
    }

    @PostMapping("/people/add")
    fun addPerson(
        @RequestBody person: Person
    ): ResponseEntity<String> {
        return ResponseEntity(personService.addPerson(person).toString(), HttpStatus.OK)
    }
}
```

We can run our tests one last time to ensure that our app still works as expected, and then we can sit back and admire our work!

## Wrap up

By converting our app from Java to Kotlin, we have been able to see some of the features that Kotlin offers, such as: Data Classes, Java interoperability, and Spring compatibility. We were also able to make the code in our app easier to read by reducing boilerplate code while maintaining a similar structure.

Want to learn more about Kotlin? Check out these resources:

- [Getting Started With Kotlin](https://kotlinlang.org/docs/getting-started.html?ref=blog.ippon.tech)
- [Kotlin Koans](https://play.kotlinlang.org/koans/overview?ref=blog.ippon.tech) - A set of exercises to introduce someone familiar with Java to Kotlin syntax and patterns
- [Spring Boot Kotlin Tutorial](https://spring.io/guides/tutorials/spring-boot-kotlin/?ref=blog.ippon.tech) - Get started creating a Spring Boot project completely in Kotlin.

## Related Articles

##### [![Getting Your Application Started With WebFlux](https://blog.ippon.tech/hs-fs/hubfs/Webflux%20image%20(1).png?width=520&height=294&name=Webflux%20image%20(1).png) Spring • May 7, 2024 Getting Your Application Started With WebFlux 6 min read](https://blog.ippon.tech/getting-your-application-started-with-webflux)

##### [![Webflux - Starting your journey](https://blog.ippon.tech/hs-fs/hubfs/Untitled%20design.png?width=520&height=294&name=Untitled%20design.png) Ippon • March 19, 2024 Webflux - Starting your journey 6 min read](https://blog.ippon.tech/webflux-starting-your-journey)

##### [![Introduction to Karate](https://blog.ippon.tech/hs-fs/hubfs/Imported_Blog_Media/karate-3961079_1280-3.jpg?width=520&height=294&name=karate-3961079_1280-3.jpg) cucumber • September 1, 2021 Introduction to Karate 6 min read](https://blog.ippon.tech/introduction-to-karate)

### Comments

### Subscribe to Our Blog!

Stay informed with the latest insights and updates by signing up for our weekly blog newsletter – delivered straight to your inbox!

[Back to blog homepage »](https://blog.ippon.tech/)

![IpponLogoKleinBlue](https://blog.ippon.tech/hs-fs/hubfs/IpponLogoKleinBlue.png?width=247&height=73&name=IpponLogoKleinBlue.png "IpponLogoKleinBlue")

Ippon is a consulting and expertise firm, who is convinced that technology is a source of progress for society. We help our clients leverage their digital assets to design an appropriate strategy and deploy their transformation roadmap at scale.

#### Navigation

- [Home](https://ipponusa.com/)
- [About](https://ipponusa.com/about-us/)
- [Services](https://ipponusa.com/services/)
- [Blogs](https://blog.ippon.tech/?__hstc=223043268.1036d82247623b329dfefe4e92697801.1714729179243.1714729179243.1714729179243.1&__hssc=223043268.2.1714729179244&__hsfp=803678701)
- [eBooks](https://ipponusa.com/ebooks/)
- [The Data Pour](https://info.ippon.tech/the-data-pour?__hstc=223043268.1036d82247623b329dfefe4e92697801.1714729179243.1714729179243.1714729179243.1&__hssc=223043268.2.1714729179244&__hsfp=803678701)

[Contact Us](https://ipponusa.com/contact/)

[Join Us](https://ipponusa.com/careers/)

#### Services

- [Data & Analytics](https://ipponusa.com/service/data-analytics/)
- [Cloud Strategy](https://ipponusa.com/service/cloud-strategy/)
- [Artificial Intelligence](https://ipponusa.com/service/artificial-intelligence/)
- [Operating Model](https://ipponusa.com/service/operating-model/)
- [Platform Modernization](https://ipponusa.com/service/platform-moderization/)
- [Product Innovation](https://ipponusa.com/service/product-innovation/)

#### Ippon International

- [France](https://fr.ippon.tech/?__hstc=223043268.1036d82247623b329dfefe4e92697801.1714729179243.1714729179243.1714729179243.1&__hssc=223043268.2.1714729179244&__hsfp=803678701)
- [Australia](https://au.ippon.tech/?__hstc=223043268.1036d82247623b329dfefe4e92697801.1714729179243.1714729179243.1714729179243.1&__hssc=223043268.2.1714729179244&__hsfp=803678701)

- #### Contact
- Ippon Technologies  
  [3431 West Leigh Street Richmond, VA 23230, USA](https://maps.app.goo.gl/RySm6SAwZnsxeiLz9)
- [(844) 477- 6687](tel:8444776687)
- [Sales@ipponusa.com](mailto:Sales@ipponusa.com)

<https://www.facebook.com/IpponUSA/> <https://www.youtube.com/c/ipponusa> <https://www.linkedin.com/company/ippon-technology>

©Copyright 2024 Ippon USA. All Rights Reserved.   |   [Terms and Conditions](https://ipponusa.com/privacy-policy/)   |   [Privacy Policy](https://ipponusa.com/privacy-policy/)   |   [Website by Skol Marketing](https://skolmarketing.com/)

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Davis Mohar",
    "url" : "https://blog.ippon.tech/author/davis-mohar"
  },
  "dateModified" : "2024-01-25T17:35:45.943Z",
  "datePublished" : "2021-06-17T16:35:00.000Z",
  "headline" : "Kotlin: Like Java, But Better (Part 2)",
  "image" : [ "https://blog.ippon.tech/hubfs/Imported_Blog_Media/Kotlin-Like-Java-But-Better-Jan-18-2024-06-07-29-2128-PM.png" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.ippon.tech/kotlin-like-java-but-better-part-2",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.ippon.tech/hubfs/logo_SVG.svg"
    },
    "name" : "Ippon Technologies"
  }
}
```