Kotlin Spring Boot | REST API 서버 만들기
이 글의 핵심
Kotlin Spring Boot: REST API 서버 만들기. Spring Boot 프로젝트 설정·REST Controller.
들어가며
Spring Boot는 Java 기반이지만 Kotlin으로 작성해도 동일한 스타터·빈을 그대로 씁니다. build.gradle.kts에서 의존성을 선언하며, 서비스·리포지토리를 설계도(클래스)에 맞춰 나누는 흐름이 일반적입니다.
1. Spring Boot 프로젝트 설정
build.gradle.kts
plugins {
kotlin("jvm") version "1.9.0"
kotlin("plugin.spring") version "1.9.0"
kotlin("plugin.jpa") version "1.9.0"
id("org.springframework.boot") version "3.2.0"
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.h2database:h2")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
}
Application.kt
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class Application
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
jpa:
hibernate:
ddl-auto: update
show-sql: true
2. REST Controller
UserController
package com.example.demo.controller
import com.example.demo.model.User
import com.example.demo.service.UserService
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api/users")
class UserController(private val userService: UserService) {
@GetMapping
fun getUsers(): List<User> {
return userService.findAll()
}
@GetMapping("/{id}")
fun getUser(@PathVariable id: Long): ResponseEntity<User> {
val user = userService.findById(id)
return if (user != null) {
ResponseEntity.ok(user)
} else {
ResponseEntity.notFound().build()
}
}
@PostMapping
fun createUser(@RequestBody user: User): ResponseEntity<User> {
val created = userService.save(user)
return ResponseEntity.status(HttpStatus.CREATED).body(created)
}
@PutMapping("/{id}")
fun updateUser(
@PathVariable id: Long,
@RequestBody user: User
): ResponseEntity<User> {
val updated = userService.update(id, user)
return if (updated != null) {
ResponseEntity.ok(updated)
} else {
ResponseEntity.notFound().build()
}
}
@DeleteMapping("/{id}")
fun deleteUser(@PathVariable id: Long): ResponseEntity<Void> {
val deleted = userService.delete(id)
return if (deleted) {
ResponseEntity.noContent().build()
} else {
ResponseEntity.notFound().build()
}
}
}
3. JPA Entity
User 엔티티
package com.example.demo.model
import jakarta.persistence.*
@Entity
@Table(name = "users")
data class User(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
@Column(nullable = false)
val name: String,
@Column(nullable = false, unique = true)
val email: String,
val age: Int? = null
)
4. Repository
UserRepository
package com.example.demo.repository
import com.example.demo.model.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface UserRepository : JpaRepository<User, Long> {
fun findByEmail(email: String): User?
fun findByNameContaining(keyword: String): List<User>
fun findByAgeGreaterThan(age: Int): List<User>
}
5. Service Layer
UserService
package com.example.demo.service
import com.example.demo.model.User
import com.example.demo.repository.UserRepository
import org.springframework.stereotype.Service
@Service
class UserService(private val userRepository: UserRepository) {
fun findAll(): List<User> {
return userRepository.findAll()
}
fun findById(id: Long): User? {
return userRepository.findById(id).orElse(null)
}
fun save(user: User): User {
return userRepository.save(user)
}
fun update(id: Long, user: User): User? {
val existing = findById(id) ?: return null
val updated = existing.copy(
name = user.name,
email = user.email,
age = user.age
)
return userRepository.save(updated)
}
fun delete(id: Long): Boolean {
return if (userRepository.existsById(id)) {
userRepository.deleteById(id)
true
} else {
false
}
}
}
6. 실전 예제
예제: Todo API
// Todo.kt
@Entity
data class Todo(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val title: String,
val completed: Boolean = false
)
// TodoRepository.kt
@Repository
interface TodoRepository : JpaRepository<Todo, Long> {
fun findByCompleted(completed: Boolean): List<Todo>
}
// TodoService.kt
@Service
class TodoService(private val todoRepository: TodoRepository) {
fun findAll(): List<Todo> = todoRepository.findAll()
fun save(todo: Todo): Todo = todoRepository.save(todo)
fun toggle(id: Long): Todo? {
val todo = todoRepository.findById(id).orElse(null) ?: return null
val updated = todo.copy(completed = !todo.completed)
return todoRepository.save(updated)
}
}
// TodoController.kt
@RestController
@RequestMapping("/api/todos")
class TodoController(private val todoService: TodoService) {
@GetMapping
fun getTodos(): List<Todo> = todoService.findAll()
@PostMapping
fun createTodo(@RequestBody todo: Todo): ResponseEntity<Todo> {
val created = todoService.save(todo)
return ResponseEntity.status(HttpStatus.CREATED).body(created)
}
@PutMapping("/{id}/toggle")
fun toggleTodo(@PathVariable id: Long): ResponseEntity<Todo> {
val updated = todoService.toggle(id)
return if (updated != null) {
ResponseEntity.ok(updated)
} else {
ResponseEntity.notFound().build()
}
}
}
정리
핵심 요약
- Spring Boot: Kotlin 완벽 지원
- data class: Entity 정의 간편
- 생성자 주입: 불변성 보장
- JpaRepository: CRUD 자동 제공
- ResponseEntity: HTTP 응답 제어
Kotlin의 장점
- Null 안전성:
?연산자 - 간결한 문법: 보일러플레이트 감소
- 확장 함수: 유틸리티 추가 용이
- 코루틴: 비동기 처리 간편
다음 단계
관련 글
- Java Spring Boot | REST API 서버 만들기
- C++ HTTP 클라이언트 완벽 가이드 | REST API 호출·연결 풀·타임아웃·프로덕션 패턴
- C++ JSON 파싱 완벽 가이드 | nlohmann·RapidJSON·커스텀 타입·에러 처리·프로덕션 패턴
- C++ REST API 클라이언트 완벽 가이드 | CRUD·인증·에러 처리·프로덕션 패턴 [#21-3]
- [Go 2주 완성 #08] Day 14: 실전 미니 프로젝트 - REST API 서버 구축
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Kotlin Spring Boot: REST API 서버 만들기. Spring Boot 프로젝트 설정·REST Controller로 흐름을 잡고 원리·코드·실무 적용을 한글로 정리합니다. Start now. 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. Kotlin 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- Java Spring Boot | REST API 서버 만들기
- Kotlin 테스팅 | JUnit, MockK, 테스트 작성법
- Java Stream API | filter, map, reduce 완벽 정리
이 글에서 다루는 키워드 (관련 검색어)
Kotlin, Spring, SpringBoot, REST API 등으로 검색하시면 이 글이 도움이 됩니다.