<!--- TEST_NAME BasicSerializationTest -->

# Basic Serialization

This is the first chapter of the [Kotlin Serialization Guide](serialization-guide.md).
This chapter shows the basic use of Kotlin Serialization and explains its core concepts.

**Table of contents**

<!--- TOC -->

* [Basics](#basics)
  * [JSON encoding](#json-encoding)
  * [JSON decoding](#json-decoding)
* [Serializable classes](#serializable-classes)
  * [Backing fields are serialized](#backing-fields-are-serialized)
  * [Constructor properties requirement](#constructor-properties-requirement)
  * [Data validation](#data-validation)
  * [Optional properties](#optional-properties)
  * [Optional property initializer call](#optional-property-initializer-call)
  * [Required properties](#required-properties)
  * [Transient properties](#transient-properties)
  * [Defaults are not encoded by default](#defaults-are-not-encoded-by-default)
  * [Nullable properties](#nullable-properties)
  * [Type safety is enforced](#type-safety-is-enforced)
  * [Referenced objects](#referenced-objects)
  * [No compression of repeated references](#no-compression-of-repeated-references)
  * [Generic classes](#generic-classes)
  * [Serial field names](#serial-field-names)

<!--- END -->

## Basics

To convert an object tree to a string or to a sequence of bytes, it must come
through two mutually intertwined processes. In the first step, an object is _serialized_&mdash;it
is converted into a serial sequence of its constituting primitive values. This process is common for all
data formats and its result depends on the object being serialized. A _serializer_ controls this process.
The second step is called _encoding_&mdash;it is the conversion of the corresponding sequence of primitives into
the output format representation. An _encoder_ controls this process. Whenever the distinction is not important,
both the terms of encoding and serialization are used interchangeably.

```
+---------+  Serialization  +------------+  Encoding  +---------------+
| Objects | --------------> | Primitives | ---------> | Output format |
+---------+                 +------------+            +---------------+
```

The reverse process starts with parsing of the input format and _decoding_ of primitive values,
followed by _deserialization_ of the resulting stream into objects. We'll see details of this process later.

For now, we start with [JSON](https://json.org) encoding.

<!--- INCLUDE .*-basic-.*
import kotlinx.serialization.*
import kotlinx.serialization.json.*
-->

### JSON encoding

The whole process of converting data into a specific format is called _encoding_. For JSON we encode data
using the [Json.encodeToString][kotlinx.serialization.encodeToString] extension function. It serializes
the object that is passed as its parameter under the hood and encodes it to a JSON string.

Let's start with a class describing a project and try to get its JSON representation.

```kotlin
class Project(val name: String, val language: String)

fun main() {
    val data = Project("kotlinx.serialization", "Kotlin")
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-basic-01.kt).

When we run this code we get the exception.

```text
Exception in thread "main" kotlinx.serialization.SerializationException: Serializer for class 'Project' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
```

<!--- TEST LINES_START -->

Serializable classes have to be explicitly marked. Kotlin Serialization does not use reflection,
so you cannot accidentally deserialize a class which was not supposed to be serializable. We fix it by
adding the [`@Serializable`][Serializable] annotation.

```kotlin
@Serializable
class Project(val name: String, val language: String)

fun main() {
    val data = Project("kotlinx.serialization", "Kotlin")
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-basic-02.kt).

The `@Serializable` annotation instructs the Kotlin Serialization plugin to automatically generate and hook
up a _serializer_ for this class. Now the output of the example is the corresponding JSON.

```text
{"name":"kotlinx.serialization","language":"Kotlin"}
```

<!--- TEST -->

> There is a whole chapter about the [Serializers](serializers.md). For now, it is enough to know
> that they are automatically generated by the Kotlin Serialization plugin.

### JSON decoding

The reverse process is called _decoding_. To decode a JSON string into an object, we'll
use the [Json.decodeFromString][kotlinx.serialization.decodeFromString] extension function.
To specify which type we want to get as a result, we provide a type parameter to this function.

As we'll see later, serialization works with different kinds of classes.
Here we are marking our `Project` class as a `data class`, not because it is required, but because
we want to print its contents to verify how it decodes.

```kotlin
@Serializable
data class Project(val name: String, val language: String)

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization","language":"Kotlin"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-basic-03.kt).

Running this code we get back the object.

```text
Project(name=kotlinx.serialization, language=Kotlin)
```

<!--- TEST -->

## Serializable classes

This section goes into more details on how different `@Serializable` classes are handled.

<!--- INCLUDE .*-classes-.*
import kotlinx.serialization.*
import kotlinx.serialization.json.*
-->

### Backing fields are serialized

Only a class's properties with backing fields are serialized, so properties with a getter/setter that don't
have a backing field and delegated properties are not serialized, as the following example shows.

```kotlin
@Serializable
class Project(
    // name is a property with backing field -- serialized
    var name: String
) {
    var stars: Int = 0 // property with a backing field -- serialized

    val path: String // getter only, no backing field -- not serialized
        get() = "kotlin/$name"

    var id by ::name // delegated property -- not serialized
}

fun main() {
    val data = Project("kotlinx.serialization").apply { stars = 9000 }
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-01.kt).

We can clearly see that only the `name` and `stars` properties are present in the JSON output.

```text
{"name":"kotlinx.serialization","stars":9000}
```

<!--- TEST -->

### Constructor properties requirement

If we want to define the `Project` class so that it takes a path string, and then
deconstructs it into the corresponding properties, we might be tempted to write something like the code below.

```kotlin
@Serializable
class Project(path: String) {
    val owner: String = path.substringBefore('/')
    val name: String = path.substringAfter('/')
}
```

<!--- CLEAR -->

This class does not compile because the `@Serializable` annotation requires that all parameters of the class's primary
constructor be properties. A simple workaround is to define a private primary constructor with the class's
properties, and turn the constructor we wanted into the secondary one.

```kotlin
@Serializable
class Project private constructor(val owner: String, val name: String) {
    constructor(path: String) : this(
        owner = path.substringBefore('/'),
        name = path.substringAfter('/')
    )

    val path: String
        get() = "$owner/$name"
}
```

Serialization works with a private primary constructor, and still serializes only backing fields.

```kotlin
fun main() {
    println(Json.encodeToString(Project("kotlin/kotlinx.serialization")))
}
```

> You can get the full code [here](../guide/example/example-classes-02.kt).

This example produces the expected output.

```text
{"owner":"kotlin","name":"kotlinx.serialization"}
```

<!--- TEST -->

### Data validation

Another case where you might want to introduce a primary constructor parameter without a property is when you
want to validate its value before storing it to a property. To make it serializable you shall replace it
with a property in the primary constructor, and move the validation to an `init { ... }` block.

```kotlin
@Serializable
class Project(val name: String) {
    init {
        require(name.isNotEmpty()) { "name cannot be empty" }
    }
}
```

A deserialization process works like a regular constructor in Kotlin and calls all `init` blocks, ensuring that you
cannot get an invalid class as a result of deserialization. Let's try it.

```kotlin
fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":""}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-03.kt).

Running this code produces the exception:

```text
Exception in thread "main" java.lang.IllegalArgumentException: name cannot be empty
```

<!--- TEST LINES_START -->

### Optional properties

An object can be deserialized only when all its properties are present in the input.
For example, run the following code.

```kotlin
@Serializable
data class Project(val name: String, val language: String)

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-04.kt).

It produces the exception:

```text
Exception in thread "main" kotlinx.serialization.MissingFieldException: Field 'language' is required for type with serial name 'example.exampleClasses04.Project', but it was missing at path: $
```

<!--- TEST LINES_START -->

This problem can be fixed by adding a default value to the property, which automatically makes it optional
for serialization.

```kotlin
@Serializable
data class Project(val name: String, val language: String = "Kotlin")

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-05.kt).

It produces the following output with the default value for the `language` property.

```text
Project(name=kotlinx.serialization, language=Kotlin)
```

<!--- TEST -->

### Optional property initializer call

When an optional property is present in the input, the corresponding initializer for this
property is not even called. This is a feature designed for performance, so be careful not
to rely on side effects in initializers. Consider the example below.

```kotlin
fun computeLanguage(): String {
    println("Computing")
    return "Kotlin"
}

@Serializable
data class Project(val name: String, val language: String = computeLanguage())

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization","language":"Kotlin"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-06.kt).

Since the `language` property was specified in the input, we don't see the "Computing" string printed
in the output.

```text
Project(name=kotlinx.serialization, language=Kotlin)
```

<!--- TEST -->

### Required properties

A property with a default value can be required in a serial format with the [`@Required`][Required] annotation.
Let us change the previous example by marking the `language` property as `@Required`.

```kotlin
@Serializable
data class Project(val name: String, @Required val language: String = "Kotlin")

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-07.kt).

We get the following exception.

```text
Exception in thread "main" kotlinx.serialization.MissingFieldException: Field 'language' is required for type with serial name 'example.exampleClasses07.Project', but it was missing at path: $
```

<!--- TEST LINES_START -->

### Transient properties

A property can be excluded from serialization by marking it with the [`@Transient`][Transient] annotation
(don't confuse it with [kotlin.jvm.Transient]). Transient properties must have a default value.

```kotlin
@Serializable
data class Project(val name: String, @Transient val language: String = "Kotlin")

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization","language":"Kotlin"}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-08.kt).

Attempts to explicitly specify its value in the serial format, even if the specified
value is equal to the default one, produces the following exception.

```text
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 42: Encountered an unknown key 'language' at path: $.name
Use 'ignoreUnknownKeys = true' in 'Json {}' builder to ignore unknown keys.
```

<!--- TEST LINES_START -->

> The 'ignoreUnknownKeys' feature is explained in the [Ignoring Unknown Keys section](json.md#ignoring-unknown-keys) section.

### Defaults are not encoded by default

Default values are not encoded by default in JSON. This behavior is motivated by the fact that in most real-life scenarios
such configuration reduces visual clutter, and saves the amount of data being serialized.

```kotlin
@Serializable
data class Project(val name: String, val language: String = "Kotlin")

fun main() {
    val data = Project("kotlinx.serialization")
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-09.kt).

It produces the following output, which does not have the `language` property because its value is equal to the default one.

```text
{"name":"kotlinx.serialization"}
```

<!--- TEST -->

See JSON's [Encoding defaults](json.md#encoding-defaults) section on how this behavior can be configured for JSON.
Additionally, this behavior can be controlled without taking format settings into account.
For that purposes, [EncodeDefault] annotation can be used:

```kotlin
@Serializable
@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now
data class Project(
    val name: String,
    @EncodeDefault val language: String = "Kotlin"
)
```

This annotation instructs the framework to always serialize property, regardless of its value or format settings.
It's also possible to tweak it into the opposite behavior using [EncodeDefault.Mode] parameter:

```kotlin

@Serializable
@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now
data class User(
    val name: String,
    @EncodeDefault(EncodeDefault.Mode.NEVER) val projects: List<Project> = emptyList()
)

fun main() {
    val userA = User("Alice", listOf(Project("kotlinx.serialization")))
    val userB = User("Bob")
    println(Json.encodeToString(userA))
    println(Json.encodeToString(userB))
}
```

> You can get the full code [here](../guide/example/example-classes-10.kt).

As you can see, `language` property is preserved and `projects` is omitted:

```text
{"name":"Alice","projects":[{"name":"kotlinx.serialization","language":"Kotlin"}]}
{"name":"Bob"}
```

<!--- TEST -->

### Nullable properties

Nullable properties are natively supported by Kotlin Serialization.

```kotlin
@Serializable
class Project(val name: String, val renamedTo: String? = null)

fun main() {
    val data = Project("kotlinx.serialization")
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-11.kt).

This example does not encode `null` in JSON because [Defaults are not encoded](#defaults-are-not-encoded).

```text
{"name":"kotlinx.serialization"}
```

<!--- TEST -->

### Type safety is enforced

Kotlin Serialization strongly enforces the type safety of the Kotlin programming language.
In particular, let us try to decode a `null` value from a JSON object into a non-nullable Kotlin property `language`.

```kotlin
@Serializable
data class Project(val name: String, val language: String = "Kotlin")

fun main() {
    val data = Json.decodeFromString<Project>("""
        {"name":"kotlinx.serialization","language":null}
    """)
    println(data)
}
```

> You can get the full code [here](../guide/example/example-classes-12.kt).

Even though the `language` property has a default value, it is still an error to attempt to assign
the `null` value to it.

```text
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 52: Expected string literal but 'null' literal was found at path: $.language
Use 'coerceInputValues = true' in 'Json {}' builder to coerce nulls if property has a default value.
```

<!--- TEST LINES_START -->

> It might be desired, when decoding 3rd-party JSONs, to coerce `null` to a default value.
> The corresponding feature is explained in the [Coercing input values](json.md#coercing-input-values) section.

### Referenced objects

Serializable classes can reference other classes in their serializable properties.
The referenced classes must be also marked as `@Serializable`.

```kotlin
@Serializable
class Project(val name: String, val owner: User)

@Serializable
class User(val name: String)

fun main() {
    val owner = User("kotlin")
    val data = Project("kotlinx.serialization", owner)
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-13.kt).

When encoded to JSON it results in a nested JSON object.

```text
{"name":"kotlinx.serialization","owner":{"name":"kotlin"}}
```

> References to non-serializable classes can be marked as [Transient properties](#transient-properties), or a
> custom serializer can be provided for them as shown in the [Serializers](serializers.md) chapter.

<!--- TEST -->

### No compression of repeated references

Kotlin Serialization is designed for encoding and decoding of plain data. It does not support reconstruction
of arbitrary object graphs with repeated object references. For example, let us try to serialize an object
that references the same `owner` instance twice.

```kotlin
@Serializable
class Project(val name: String, val owner: User, val maintainer: User)

@Serializable
class User(val name: String)

fun main() {
    val owner = User("kotlin")
    val data = Project("kotlinx.serialization", owner, owner)
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-14.kt).

We simply get the `owner` value encoded twice.

```text
{"name":"kotlinx.serialization","owner":{"name":"kotlin"},"maintainer":{"name":"kotlin"}}
```

> Attempt to serialize a circular structure will result in stack overflow.
> You can use the [Transient properties](#transient-properties) to exclude some references from serialization.

<!--- TEST -->

### Generic classes

Generic classes in Kotlin provide type-polymorphic behavior, which is enforced by Kotlin Serialization at
compile-time. For example, consider a generic serializable class `Box<T>`.

```kotlin
@Serializable
class Box<T>(val contents: T)
```

The `Box<T>` class can be used with builtin types like `Int`, as well as with user-defined types like `Project`.

<!--- INCLUDE

@Serializable
data class Project(val name: String, val language: String)
-->

```kotlin
@Serializable
class Data(
    val a: Box<Int>,
    val b: Box<Project>
)

fun main() {
    val data = Data(Box(42), Box(Project("kotlinx.serialization", "Kotlin")))
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-15.kt).

The actual type that we get in JSON depends on the actual compile-time type parameter that was specified for `Box`.

```text
{"a":{"contents":42},"b":{"contents":{"name":"kotlinx.serialization","language":"Kotlin"}}}
```

<!--- TEST -->

If the actual generic type is not serializable a compile-time error will be produced.

### Serial field names

The names of the properties used in encoded representation, JSON in our examples, are the same as
their names in the source code by default. The name that is used for serialization is called a _serial name_, and
can be changed using the [`@SerialName`][SerialName] annotation. For example, we can have a `language` property in
the source with an abbreviated serial name.

```kotlin
@Serializable
class Project(val name: String, @SerialName("lang") val language: String)

fun main() {
    val data = Project("kotlinx.serialization", "Kotlin")
    println(Json.encodeToString(data))
}
```

> You can get the full code [here](../guide/example/example-classes-16.kt).

Now we see that an abbreviated name `lang` is used in the JSON output.

```text
{"name":"kotlinx.serialization","lang":"Kotlin"}
```

<!--- TEST -->

---

The next chapter covers [Builtin classes](builtin-classes.md).

<!-- stdlib references -->
[kotlin.jvm.Transient]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-transient/

<!--- MODULE /kotlinx-serialization-core -->
<!--- INDEX kotlinx-serialization-core/kotlinx.serialization -->

[kotlinx.serialization.encodeToString]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/encode-to-string.html
[Serializable]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-serializable/index.html
[kotlinx.serialization.decodeFromString]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/decode-from-string.html
[Required]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-required/index.html
[Transient]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-transient/index.html
[EncodeDefault]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-encode-default/index.html
[EncodeDefault.Mode]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-encode-default/-mode/index.html
[SerialName]: https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-serial-name/index.html

<!--- MODULE /kotlinx-serialization-json -->
<!--- INDEX kotlinx-serialization-json/kotlinx.serialization.json -->
<!--- END -->
