JSON을 Kotlin Data Class로 변환 — Null Safety 가이드

JSON을 Kotlin data class로 바로 변환하는 작업 화면

nullable 규칙과 중첩 객체 구조를 Kotlin 관점에서 검토할 수 있도록 구성한 전용 페이지입니다.

Input

JSON Payload

JSON을 Kotlin data class로 바로 변환하고 nullable, nested object 구조를 같은 화면에서 검토할 수 있습니다.

{
  "orderId": "ORD-2026-001",
  "status": "PAID",
  "amount": 12900,
  "customer": {
    "name": "Lee",
    "email": "lee@example.com"
  }
}

Output

생성 예시

data class ProfilePayload(
  val profileId: String,
  val nickname: String,
  val marketing: Boolean,
  val tags: List<String>?,
  val contact: Contact
)

Explanation

왜 Kotlin data class가 좋은가

Kotlin은 nullability를 타입에 직접 드러내기 때문에 JSON 샘플을 모델링할 때 계약 판단이 더 명확해집니다.

Kotlin data class가 잘 맞는 이유

Kotlin data class는 생성자 기반 모델링, `copy`, `equals`, `hashCode`, 구조 분해 같은 기능을 기본으로 제공합니다. 그래서 API 응답 모델, Android UI state, 서버리스 함수 입출력 모델을 만들 때 특히 효율적입니다.

JSON2Class로 초안을 만들면 중첩 객체와 리스트 구조를 빠르게 확인할 수 있고, 이후 `@Serializable`, `@Json`, `@SerialName` 같은 프레임워크 어노테이션을 필요한 필드에만 추가하면 됩니다.

JSON과 Kotlin 타입 매핑 예시

이 예시에서 핵심은 nullable 표현입니다. Kotlin은 `String`과 `String?`의 차이가 명확하기 때문에, 샘플 JSON에 null이 실제로 들어오는지 확인하는 일이 Java보다 더 중요합니다.

입력 JSON

{
  "id": "profile-01",
  "nickname": "neo",
  "marketing": true,
  "tags": ["vip", "beta"],
  "contact": {
    "email": "neo@example.com",
    "phone": null
  }
}

생성 예시

data class ProfilePayload(
  val id: String,
  val nickname: String,
  val marketing: Boolean,
  val tags: List<String>?,
  val contact: Contact
)

data class Contact(
  val email: String,
  val phone: String?
)

Android와 서버 환경에서의 사용 사례

Android에서는 네트워크 계층의 응답 모델을 UI 모델과 구분하는 경우가 많습니다. JSON2Class 출력은 응답 DTO 초안으로 쓰고, 이후 Mapper를 통해 Compose 상태 모델로 변환하면 화면 레이어를 더 깔끔하게 유지할 수 있습니다.

Spring Boot나 Ktor 같은 서버 환경에서도 요청/응답 payload 정의를 data class로 두면 테스트와 직렬화 코드가 간결해집니다. 특히 이벤트 payload나 내부 서비스 간 JSON 계약을 다룰 때 data class는 읽기 쉬운 선택입니다.

자주 겪는 문제

첫 번째는 네이밍입니다. snake_case를 camelCase로 바꾸고 싶지만 원본 키도 유지해야 한다면 `@SerialName` 또는 `@JsonProperty`가 필요합니다.

두 번째는 nested object 분리 기준입니다. 생성 결과가 하나의 파일에 길게 나오는 것은 검토용으로는 좋지만, 실제 프로젝트에서는 파일 단위로 분리해 재사용하는 편이 더 낫습니다.

세 번째는 날짜와 enum 후보입니다. JSON 샘플에서는 문자열로만 보이지만, 실제로는 enum이나 `Instant`가 더 적절한 경우가 많으므로 도메인 규칙을 반영해 후처리해야 합니다.

nullability를 먼저 정리해야 하는 이유

Kotlin에서는 nullable 판정이 코드 전반에 영향을 줍니다. 필드를 무심코 `String?`로 두면 이후 화면 로직과 도메인 로직에 null 체크가 퍼지고, 반대로 너무 엄격하게 `String`으로 고정하면 역직렬화 단계에서 바로 예외가 납니다.

따라서 샘플 JSON 하나만 보기보다, 성공/실패/비정상 응답 예시를 함께 모아 data class 초안을 잡는 편이 좋습니다. JSON2Class는 이 출발점을 빠르게 만드는 도구로 생각하면 적절합니다.

실무 체크리스트

이 체크리스트를 기준으로 보면, 생성된 data class는 최종 코드라기보다 검토 가능한 설계 문서에 가깝습니다. Kotlin에서는 작은 모델 여러 개로 나누는 편이 훨씬 읽기 좋기 때문에, 생성 결과를 과감히 분리하는 것이 일반적입니다.

  • 서버가 누락 가능한 필드와 명시적으로 null을 보내는 필드를 구분
  • 문자열 timestamp를 `Instant`, `LocalDateTime`, `String` 중 무엇으로 유지할지 결정
  • 동적 key 구조는 data class보다 `Map<String, T>`가 맞는지 검토
  • 화면 모델과 네트워크 모델을 같은 data class로 쓸지 분리할지 결정

협업에 유리한 이유

같은 JSON을 Java, TypeScript, Kotlin으로 동시에 확인할 수 있으면 모바일, 웹, 백엔드가 같은 계약을 놓고 빠르게 얘기할 수 있습니다. 타입명이 어디서 바뀌었는지, nullability 해석이 왜 다른지 논의하는 시간이 줄어듭니다.

특히 Android 앱에서는 API 계약이 변경될 때 화면 크래시로 이어지기 쉽기 때문에, data class 초안을 빠르게 만들고 리뷰 단계에서 도메인 규칙을 추가하는 흐름이 안정적입니다.

Related Tools

같이 보면 좋은 도구

언어별 변환기와 JSON 보조 도구를 연결해 내부 링크 구조를 강화했습니다.

JSON to Java

Java DTO와 validation 중심으로 JSON 응답 모델을 정리합니다.

JSON Formatter

샘플 JSON을 정리한 뒤 변환기에 다시 넣어 타입 추론을 안정화합니다.