Spring Boot 프로젝트에 데이터 클래스 추가하기
Spring Boot 프로젝트에 데이터 클래스 추가하기 (Add a data class to Spring Boot project)
이 튜토리얼 파트에서는 애플리케이션에 기능을 좀 더 추가하면서 데이터 클래스 같은 Kotlin 언어 기능을 더 알아보게 돼요. MessageController 클래스를 바꿔 직렬화된 객체 컬렉션을 담은 JSON 문서로 응답하게 만들 겁니다.
본문
이번 파트에서는 애플리케이션에 기능을 조금 더 추가하고, 데이터 클래스 같은 Kotlin 언어 기능을 더 살펴봐요. 이를 위해 MessageController 클래스를 바꿔 직렬화된 객체 컬렉션을 담은 JSON 문서로 응답하도록 만들 것입니다.
애플리케이션 업데이트하기 (Update your application)
DemoApplication.kt파일과 같은 패키지에Message.kt파일을 만들어요.Message.kt파일에id와text두 프로퍼티를 가진 데이터 클래스를 만듭니다.
// Message.kt
package com.example.demo
data class Message(val id: String?, val text: String)
Message 클래스는 데이터 전송에 쓰일 거예요. 직렬화된 Message 객체 목록이 브라우저 요청에 컨트롤러가 응답할 JSON 문서를 구성합니다.
데이터 클래스 – data class Message
Kotlin에서 데이터 클래스의 주 목적은 데이터를 담는 것이에요. 이런 클래스는 data 키워드로 표시하며, 표준 기능 일부와 유틸리티 함수 몇 가지가 클래스 구조에서 기계적으로 파생됩니다.
이 예시에서는 Message의 주 목적이 데이터를 저장하는 것이므로 데이터 클래스로 선언했어요.
val과 var 프로퍼티
Kotlin의 프로퍼티는 두 방식 중 하나로 선언할 수 있어요.
var키워드를 쓰는 가변(mutable) 프로퍼티val키워드를 쓰는 읽기 전용(read-only) 프로퍼티
Message 클래스는 val 키워드로 id와 text 두 프로퍼티를 선언합니다. 컴파일러는 두 프로퍼티 모두에 대해 getter를 자동으로 생성해요. Message 클래스의 인스턴스가 만들어진 뒤에는 이 프로퍼티들의 값을 다시 할당할 수 없습니다.
널 가능 타입 – String?
Kotlin은 널 가능 타입을 기본 지원해요. Kotlin의 타입 시스템은 null을 담을 수 있는 참조(nullable reference)와 담을 수 없는 참조(non-nullable reference)를 구분합니다. 예를 들어 String 타입의 일반 변수는 null을 담을 수 없어요. null을 허용하려면 String?으로 써서 변수를 널 가능 문자열로 선언하면 됩니다.
이번에는 Message 클래스의 id 프로퍼티가 널 가능 타입으로 선언됩니다. 따라서 id 값으로 null을 넘겨 Message 클래스의 인스턴스를 만들 수 있어요.
Message(null, "Hello!")
MessageController.kt파일에서index()함수 대신Message객체 목록을 반환하는listMessages()함수를 만들어요.
// MessageController.kt
package com.example.demo
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/")
class MessageController {
@GetMapping
fun listMessages() = listOf(
Message("1", "Hello!"),
Message("2", "Bonjour!"),
Message("3", "Privet!"),
)
}
컬렉션 – listOf()
Kotlin 표준 라이브러리는 집합(set), 목록(list), 맵(map) 같은 기본 컬렉션 타입 구현을 제공해요. 각 컬렉션 타입은 읽기 전용이거나 *가변(mutable)*일 수 있습니다.
- 읽기 전용 컬렉션은 컬렉션 요소에 접근하는 연산을 제공해요.
- 가변 컬렉션은 요소 추가, 제거, 갱신을 위한 쓰기 연산도 함께 제공합니다.
Kotlin 표준 라이브러리는 이런 컬렉션의 인스턴스를 만들 수 있는 팩토리 함수도 제공해요.
이 튜토리얼에서는 listOf() 함수로 Message 객체 목록을 만듭니다. 이 함수는 읽기 전용 객체 목록을 만드는 팩토리 함수라서 목록에서 요소를 추가하거나 제거할 수 없어요. 목록에 쓰기 연산이 필요하다면 mutableListOf() 함수를 호출해 가변 목록 인스턴스를 만드세요.
후행 쉼표 (Trailing comma)
후행 쉼표(trailing comma)는 요소 나열에서 마지막 항목 뒤에 붙는 쉼표예요.
Message("3", "Privet!"),
Kotlin 문법의 편리한 기능으로 완전히 선택 사항이라, 없어도 코드는 그대로 동작합니다.
위 예시에서 Message 객체 목록을 만들 때 listOf() 함수의 마지막 인자 뒤에 후행 쉼표가 붙었어요.
이제 MessageController의 응답은 Message 객체 컬렉션을 담은 JSON 문서가 됩니다.
Spring 애플리케이션의 어떤 컨트롤러든 Jackson 라이브러리가 클래스패스에 있으면 기본적으로 JSON 응답을 렌더링해요. 이전에
build.gradle.kts파일에spring-boot-starter-webmvc의존성을 지정했기 때문에 Jackson을 전이(transitive) 의존성으로 받았습니다. 따라서 엔드포인트가 JSON으로 직렬화할 수 있는 데이터 구조를 반환하면 애플리케이션은 JSON 문서로 응답해요.
DemoApplication.kt, MessageController.kt, Message.kt 파일의 전체 코드는 다음과 같습니다.
// DemoApplication.kt
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
// MessageController.kt
package com.example.demo
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/")
class MessageController {
@GetMapping
fun listMessages() = listOf(
Message("1", "Hello!"),
Message("2", "Bonjour!"),
Message("3", "Privet!"),
)
}
// Message.kt
package com.example.demo
data class Message(val id: String?, val text: String)
애플리케이션 실행하기 (Run the application)
Spring 애플리케이션은 실행할 준비가 됐어요.
- 애플리케이션을 다시 실행해요.
- 애플리케이션이 시작되면 다음 URL을 엽니다.
http://localhost:8080
JSON 형식의 메시지 컬렉션이 담긴 페이지를 볼 수 있어요.
다음 단계 (Next step)
튜토리얼의 다음 파트에서는 프로젝트에 데이터베이스를 추가·구성하고 HTTP 요청을 하게 됩니다.