Membuat REST API dengan Spring Boot dan Kotlin

REST API dengan Webmvc dan Kotlin Language

Membuat REST API dengan Spring Boot dan Kotlin

Hallo guys, alhamdulilah sekarang saya sudah bisa meluangkan waktu untuk menulis kembali artikel yang lain, maaf dikarena kan saya dipindahkan ke tim lain di tempat saya bekerja jadi saya ada beberapa penyesuaian kembali yang cukup memakan waktu πŸ˜… πŸ™.

Kenapa Kotlin ? yaa, mungkin kalian ada yang bertanya seperti itu ? dan saya pun sebenarnya terpaksa belajar Kotlin gara2 pindah tim tadi, tapi pas pertama kali coba, ehh koo, koo enakk πŸ˜†πŸ˜†πŸ˜†πŸ˜†. Banyak boilerplate code yang bisa diringkas jika kita menggunakan Kotlin dibanding Java. dan saya pun berpikir "kenapa ga dari dulu coba kotlin ? πŸ˜†πŸ˜†πŸ˜†πŸ˜†πŸ˜†πŸ˜†πŸ˜†".

Use Case

Ok udah cukup basa basi nya, dalam artikel ini, kita akan membuat sebuah simple Restful API untuk mengelola data employee. Sehingga admin bisa mendapatkan akses :

  • Membuat employee

  • Melihat Daftar Employee

  • Memperbaharui data Employee

  • Mendapatkan data Employee berdasarkan ID

  • Menghapus data Employee

Data Employee disini mempunyai :

  • username

  • first name

  • last name

  • email

  • data or birth

Dimana username dari suatu employee ini sifat nya unique sehingga tidak akan ada data dua employee dengan username yang sama.

Setup Project

Seperti biasa, dalam membuat project Spring Boot kita bisa membuat dengan dua cara yaitu :

  • Menggunakan IDE (Inteljidea / Spring Tool Suite )

  • Menggunakan Spring Initializer

Namun dalam artikel ini, saya menggunakan Spring Initializer dan kalian bisa mengakses pada web https://start.spring.io/

Dalam project ini kita akan menggunakan :

  • Spring Web

  • Spring Data JPA

  • H2 Database

  • JDK 17 (Bisa disesuaikan)

  • Kotlin Language

  • Gradle Kotlin (Gradle wrapper sehingga kalian tidak perlu install gradle di local)

Buka project tersebut menggunakan IDE dan download semua dependencies nya.

Setting Properties

Langkah selanjutnya yaitu melakukan pengaturan properties file pada file application.properties. Ubah file tersebut menjadi application.yml*. Mengapa menggunakan yaml file ? karena kita ingin menghindari penulisan berulang (repetitive) yang biasa terjadi ketika kita mengulis property pada file **application.properties*

spring:
  datasource:
    driver-class-name: "org.h2.Driver"
    url: jdbc:h2:mem:dev_db
    username: sa
    password: password
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    generate-ddl: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect

Membuat Domain Model

Karena kita ingin mengelola data employee maka buatlah sebuah folder dengan nama models dan buat sebuah file class Kotlin dengan nama Employee.kt.

Dalam Kotlin, sebuah data class akan secara otomatis membuatkan equals/hashCode pair, toString dan copy function dan kita pun tidak perlu membuatkan getter / setter seperti yang biasa kita lakukan ketika membuat kode menggunakan Java dan plugin Lombok.

package id.restfulapi.springkotlin.models

import java.time.LocalDate
import javax.persistence.*

@Entity
@Table(name = "employee")
data class Employee (
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long?,
    @Column(name = "user_name", unique = true, nullable = false)
    val userName: String,
    @Column(name = "first_name", nullable = false)
    val firstName: String,
    @Column(name = "middle_name", nullable = true)
    val middleName: String?,
    @Column(name = "last_name", nullable = false)
    val lastName: String,
    @Column(name = "email_address", nullable = false)
    val emailId: String,
    @Column(name = "day_of_birth", nullable = false)
    val dayOfBirth: LocalDate
)

bisa dilihat kita mendefinisikan atribut-atribut dalam sebuah parameter dalam kurung buka dan kurung tutup

data class Employee (....)

Membuat Repository

Karena kita akan berinteraksi dengan database maka kita perlu membuat sebuah interface repository. Interface ini akan extend dari JpaRepository . Class ini akan menyediakan fungsi dasar CRUD dari class employee.

Untuk itu buatlah sebuah folder dengan nama repository dan buat sebuah interface dengan nama EmployeeRepository.kt

package id.restfulapi.springkotlin.repository

import id.restfulapi.springkotlin.models.Employee
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface EmployeeRepository: JpaRepository<Employee, Long>{
}

annotasi @Repository diatas, menspesifikasikan bahwa interface ini adalah sebuah repository yang merepresentasikan data access layer dalam aplikasi kita

Service

Sekarang kita masuk kedalam bisnis logic aplikasi yang akan kita buat. Sesuai dengan yang saya mention di bab Use Case kita akan membuat implementasi itu pada layer ini. Untuk itu buatlah sebuah folder dengan nama service dan buat sebuah class Kotlin dengan nama EmployeeService.kt

Jangan lupa gunakan annotasi @Service dan panggil employeeRepository yang telah kita buat diatas.

package id.restfulapi.springkotlin.service

import id.restfulapi.springkotlin.exception.EmployeeNotFoundException
import id.restfulapi.springkotlin.models.Employee
import id.restfulapi.springkotlin.repository.EmployeeRepository
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service

@Service
class EmployeeService(private val employeeRepository: EmployeeRepository) {

    fun getAllEmployees(): List<Employee> = employeeRepository.findAll()

    fun getEmployeesById(employeeId: Long): Employee = employeeRepository.findById(employeeId)
        .orElseThrow { EmployeeNotFoundException(HttpStatus.NOT_FOUND, "No matching employee was found") }

    fun createEmployee(employee: Employee): Employee = employeeRepository.save(employee)

    fun updateEmployeeById(employeeId: Long, employee: Employee): Employee {
        return if (employeeRepository.existsById(employeeId)) {
            employeeRepository.save(
                Employee(
                    id = employee.id,
                    userName = employee.userName,
                    firstName = employee.firstName,
                    middleName = employee.middleName,
                    lastName = employee.lastName,
                    emailId = employee.emailId,
                    dayOfBirth = employee.dayOfBirth
                )
            )
        } else throw EmployeeNotFoundException(HttpStatus.NOT_FOUND, "No matching employee was found")
    }

    fun deleteEmployeesById(employeeId: Long) {
        return if (employeeRepository.existsById(employeeId)) {
            employeeRepository.deleteById(employeeId)
        } else throw EmployeeNotFoundException(HttpStatus.NOT_FOUND, "No matching employee was found")
    }
}

kita menggunakan custom exception dengan nama EmployeeNotFoundException yang merepresentasikan bahwa data yang dicari tidak ada. Untuk itu, buat sebuah file EmployeeNotFoundException.kt pada folder exception

package id.restfulapi.springkotlin.exception

import org.springframework.http.HttpStatus

class EmployeeNotFoundException(val statusCode: HttpStatus, val reason: String) : Exception()

Controller

Kita akan mengimplementasikan sebuah REST API untuk semua CRUD operasi yang telah kita buat di layer service, buat sebuah folder controller dan buat sebuah class baru dengan nama EmployeeController.kt pada folder tersebut.

package id.restfulapi.springkotlin.controller

import id.restfulapi.springkotlin.models.Employee
import id.restfulapi.springkotlin.service.EmployeeService
import org.springframework.web.bind.annotation.*

@RestController
class EmployeeController(private val employeeService: EmployeeService) {

    @GetMapping("/employees")
    fun getAllEmployees(): List<Employee> = employeeService.getAllEmployees()

    @GetMapping("/employees/{id}")
    fun getEmployeesById(@PathVariable("id") employeeId: Long): Employee =
        employeeService.getEmployeesById(employeeId)

    @PostMapping("/employees")
    fun createEmployee(@RequestBody payload: Employee): Employee = employeeService.createEmployee(payload)

    @PutMapping("/employees/{id}")
    fun updateEmployeeById(@PathVariable("id") employeeId: Long, @RequestBody payload: Employee): Employee =
        employeeService.updateEmployeeById(employeeId, payload)

    @DeleteMapping("/employees/{id}")
    fun deleteEmployeesById(@PathVariable("id") employeeId: Long): Unit =
        employeeService.deleteEmployeesById(employeeId)
}

Running the application

Kita bisa menjalankan aplikasi menggunakan perintah seperti berikut

./gradlew bootRun

dan pastikan bahwa port 8080 nya sudah aktif

Explore the Endpoints

Dalam bab ini, saya menggunakan curl jika teman-teman tidak bisa menggunakan curl, kalian bisa menggunakan Rest api client seperti postman atau insomnia.

Membuat Data Employee

curl --location --request POST 'http://localhost:8080/employees' --header 'Content-Type: application/json' \
--data-raw '{
    "userName":"john.doe",
    "firstName":"John",
    "lastName":"Doe",
    "emailId":"john.doe@gmail.com",
    "dayOfBirth":"1997-12-03"
}'

dan kita akan menerima output JSON seperti

{
  "id": 1,
  "userName": "john.doe",
  "firstName": "John",
  "middleName": null,
  "lastName": "Doe",
  "emailId": "john.doe@gmail.com",
  "dayOfBirth": "1997-12-03"
}

Mendapatkan Semua Data Employee

curl --location --request GET 'http://localhost:8080/employees' --header 'Content-Type: application/json'

dan kita akan menerima output JSON seperti

[
  {
    "id": 1,
    "userName": "john.doe",
    "firstName": "John",
    "middleName": null,
    "lastName": "Doe",
    "emailId": "john.doe@gmail.com",
    "dayOfBirth": "1997-12-03"
  },
  {
    "id": 2,
    "userName": "john.doe2",
    "firstName": "John2",
    "middleName": null,
    "lastName": "Doe2",
    "emailId": "john.doe2@gmail.com",
    "dayOfBirth": "1997-12-03"
  }
]

Mendapatkan Data Employee by ID

curl --location --request GET 'http://localhost:8080/employees/1' --header 'Content-Type: application/json'

Output nya seperti berikut

[
  {
    "id": 1,
    "userName": "john.doe",
    "firstName": "John",
    "middleName": null,
    "lastName": "Doe",
    "emailId": "john.doe@gmail.com",
    "dayOfBirth": "1997-12-03"
  }
]

Mengupdate Data Employee

curl --location --request PUT 'http://localhost:8080/employees/1' --header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "userName": "john.doe",
    "firstName": "John",
    "middleName": "Thomas",
    "lastName": "Doe",
    "emailId": "john.doe7@gmail.com",
    "dayOfBirth": "1997-12-03"
}'

Output akan seperti berikut

{
  "id": 1,
  "userName": "john.doe",
  "firstName": "John",
  "middleName": "Thomas",
  "lastName": "Doe",
  "emailId": "john.doe7@gmail.com",
  "dayOfBirth": "1997-12-03"
}

Menghapus Data Employee

curl --location --request DELETE 'http://localhost:8080/employees/1' --header 'Content-Type: application/json'

Kesimpulan

Pada tahap ini, kalian sudah mempelajari bagaiman membuat simple rest api crud employee menggunakan Kotlin.
Kalian juga bisa mendapatkan source nya pada link berikut https://github.com/teten-nugraha/springboot-kotlin-restapi

Did you find this article valuable?

Support Teten Nugraha by becoming a sponsor. Any amount is appreciated!

Β