JSON to Kotlin Data Class Converter

JSON to Kotlin Data Class

Turn API response samples into Kotlin data classes. Review nullable properties and nested models, then adapt serialization to your Android or server project. Conversion runs locally in your browser.

Input

JSON Payload

Turn API response samples into Kotlin data classes. Review nullable properties and nested models, then adapt serialization to your Android or server project. Conversion runs locally in your browser.

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

Output

Generated example

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

Explanation

Why Kotlin works well

Nullability is visible in the type system, which makes generated models especially useful for API review.

Kotlin serialization: missing and null fixtures

The converter creates a structural draft. This adapted example adds Serializable, SerialName and a default value manually for kotlinx.serialization; these annotations are not generated by the Kotlin converter. Enable the serialization compiler plugin and add the JSON runtime in your project.

Here nickname: String? = null intentionally accepts both a missing key and explicit null. Removing the default makes a nullable field required under the default JSON configuration. Keep userId required and test serializer configuration changes explicitly.

Official reference

Input fixture

{"user_id":"usr-42","nickname":null}

Adapted application model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class UserResponse(
    @SerialName("user_id") val userId: String,
    val nickname: String? = null
)

Verification in your project

// Requires the Kotlin serialization compiler plugin
// and kotlinx-serialization-json in your project.
import kotlinx.serialization.json.Json

val missing = Json.decodeFromString<UserResponse>("""{"user_id":"usr-42"}""")
val explicitNull = Json.decodeFromString<UserResponse>(
    """{"user_id":"usr-42","nickname":null}"""
)
check(missing.nickname == null)
check(explicitNull.nickname == null)
check(missing.userId == "usr-42")

Distinguish missing fields from explicit null values

A field that is absent and a field that is present with null are not always equivalent. The distinction affects default constructor values, kotlinx.serialization behavior, Jackson configuration, and every caller that consumes the model. Review several real responses before adding a question mark to every property or making every property strict.

For external services, conservative nullable types may protect the app from inconsistent payloads. For internal commands, non-null types with validation at the boundary are often clearer. The correct choice follows ownership of the contract, not the value shown in one successful sample.

  • Compare success, empty-state, and error payloads
  • Use constructor defaults only when a default has real domain meaning
  • Document whether an empty list and a missing list are interchangeable

Choose serialization and naming rules

Kotlin properties normally use camelCase, while APIs may expose snake_case or names that are not valid identifiers. Preserve the wire name with SerialName, JsonProperty, or the annotation used by your serialization library. Avoid renaming payload fields manually in every mapper because that spreads protocol knowledge across the codebase.

Keep network DTOs close to the client or controller boundary. Android applications often map them into UI models, and server applications may map them into domain commands. That extra step is useful when display defaults, localization, or business invariants differ from the transport contract.

Refine dates, enums, arrays, and nested objects

ISO-looking strings may become Instant, LocalDateTime, or remain String depending on timezone semantics. Repeated status strings may become enums, but external APIs need an unknown fallback so a new server value does not crash deserialization. Empty arrays require additional examples because they reveal nothing about the element type.

Nested data classes are convenient for an initial draft. Split them into named files when they are shared or when the root model becomes difficult to read. Dynamic key objects may be better represented as Map<String, T> than as a large generated class with unstable properties.

Verify the model in the target runtime

Run serialization tests with the same library and configuration used by the application. Include missing values, explicit nulls, empty collections, unknown enum values, and timestamps with offsets. A short fixture test catches configuration differences that a browser-based generator cannot infer.

The generated class is therefore a productive starting point and a compact discussion artifact. The final model should reflect the API owner, runtime serializer, and architecture of the application that will maintain it.

Related Tools

Related tools in the same workflow

These internal links connect the language page to adjacent tools used in the same API workflow.

JSON to Java

Generate Java DTOs and review validation-oriented API models.

JSON Formatter

Format sample payloads before sending them back into the converter.