Build REST CRUD API's with Kotlin, Spring, Spring Data JPA, and RDBMS

In this article, we will show you how to develop a  REST-style web service with Kotlin, Spring Boot, H2DB.


A quick overview of Kotlin, Spring Boot, and H2DB 

 Kotlin

Kotlin is a statically typed, general-purpose programming language targeting the Java platform. Kotlin is concise, safe, pragmatic, and fixated on interoperability with Java code. It can be used virtually everywhere Java is utilized today: for server-side development, Android apps, and much more. Kotlin works great with all subsisting Java libraries and frameworks and runs with the same level of performance as Java.

H2DB[RDBMS]

H2DB is a relational database management system written in Java. It can be embedded in Java applications or run in client-server mode.

Spring Boot

Spring boot to develop REST web services and microservices. Spring Boot has taken the Spring framework to the next level. It has drastically reduced the configuration and setup time required for spring projects. We can set up a project with almost zero configuration and start building the things that actually matter to your application.

Technologies used :

  • Spring Boot 2.3.7.RELEASE
  • Spring  5.2.12.RELEASE
  • Kotlin 2.11.3
  • Hibernate 5.4.25.Final
  • H2DB
  • Maven 3
  • Java 8

After completing this tutorial what we will build? 

We will build REST API  CRUD features: 

  1. GET - Fetch all User       :     /api/v1/users
  2. GET - Get User by ID     :     /api/v1/users/{id} 
  3. POST - Create User         :     /api/v1/users 
  4. PUT - Edit User Details   :     /api/v1/users/{id} 
  5. DELETE - Delete User    :     /api/v1/users/{id}

Project Directory


 

Maven[pom.xml]

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev</groupId>
<artifactId>kotlin_springb_postgresql_restful_api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kotlin_springb_postgresql_restful_api</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<kotlin.version>1.3.72</kotlin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>


Creating the Entity[User.kt]

package com.knf.dev.entity

import javax.persistence.*

@Entity
@Table(name = "user")
data class User(

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
var id: Long,
val firstName: String,
val lastName: String,
val emailId: String
)

 

Creating the Repository[UserRepository.kt]

package com.knf.dev.repository


import com.knf.dev.entity.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface UserRepository : JpaRepository<User, Long>


Creating the controller End-points[UserController.kt]

package com.knf.dev.controller

import com.knf.dev.entity.User
import com.knf.dev.repository.UserRepository
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/api/v1/")
class UserController(private val userRepository: UserRepository) {

@GetMapping("/users")
fun getAllUsers(): List<User> =
userRepository.findAll()

@PostMapping("/users")
fun createNewUser(@RequestBody user: User): User =
userRepository.save(user)

@GetMapping("/users/{id}")
fun getUserById(@PathVariable(value = "id") userId: Long):
ResponseEntity<User> {
return userRepository.findById(userId).map { usr ->
ResponseEntity.ok(usr)
}.orElse(ResponseEntity.notFound().build())
}

@PutMapping("/users/{id}")
fun updateUserById(@PathVariable(value = "id") userId: Long,
@RequestBody newUser: User):
ResponseEntity<User> {

return userRepository.findById(userId).map { existingUser ->
val updatedEmployee: User = existingUser
.copy(firstName = newUser.firstName, lastName =
newUser.lastName, emailId = newUser.emailId)
ResponseEntity.ok().body(userRepository.save(updatedEmployee))
}.orElse(ResponseEntity.notFound().build())

}

@DeleteMapping("/users/{id}")
fun deleteUserById(@PathVariable(value = "id") userId: Long):
ResponseEntity<Void> {
return userRepository.findById(userId).map { usr ->
userRepository.delete(usr)
ResponseEntity<Void>(HttpStatus.OK)
}.orElse(ResponseEntity.notFound().build())

}
}

Main[KotlinSpringbH2DBRestfulApiApplication.tk]

package com.knf.dev

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class KotlinSpringbH2DBRestfulApiApplication

fun main(args: Array<String>) {
runApplication<KotlinSpringbH2DBRestfulApiApplication>(*args)
}

Run 

$ mvn spring-boot:run

Testing API's using Postman

Create an User



Fetch all User



Update User



Delete User By Id



Get User By Id


Download  source code



More Kotlin Examples,

Comments

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java, Spring Boot Mini Project - Library Management System - Download

Java - Blowfish Encryption and decryption Example

Java - DES Encryption and Decryption example

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete

ReactJS - Bootstrap - Buttons

Spring Boot 3 + Spring Security 6 + Thymeleaf - Registration and Login Example

File Upload, Download, And Delete - Azure Blob Storage + Spring Boot Example

Top 5 Java ORM tools - 2024

Java - How to Count the Number of Occurrences of Substring in a String