Skip to content
4 changes: 2 additions & 2 deletions docs-website/topics/serialization-json-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This allows you to control which values appear in the output and how specific ty

By default, the JSON encoder omits default property values because they are automatically applied to missing properties during decoding.
This behavior is especially useful for nullable properties with null defaults, as it avoids writing unnecessary `null` values.
For more details, see the [Manage serialization of default properties](serialization-customization-options.md#manage-the-serialization-of-default-properties-with-encodeddefault) section.
For more details, see the [Manage serialization of default properties](serialization-customization-options.md#manage-the-serialization-of-default-properties-with-encodedefault) section.

To change this default behavior, set the [`encodeDefaults`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json/kotlinx.serialization.json/-json-builder/encode-defaults.html) property to `true` in a `Json` instance:

Expand Down Expand Up @@ -605,7 +605,7 @@ fun main() {

### Lenient parsing

By default, the `Json` parser enforces strict JSON rules to ensure compliance with the [RFC-4627](https://www.ietf.org/rfc/rfc4627.txt) specification,
By default, the `Json` parser enforces strict JSON rules to ensure compliance with the [RFC-8259](https://www.ietf.org/rfc/rfc8259.txt) specification,
which requires keys and string literals to be quoted.

To relax these restrictions, set the [`isLenient`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json/kotlinx.serialization.json/-json-builder/is-lenient.html) property to `true` in a `Json` instance:
Expand Down
127 changes: 100 additions & 27 deletions docs-website/topics/serialization-json-io-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

The Kotlin serialization library provides APIs for working with JVM streams and [`kotlinx-io`](https://github.com/Kotlin/kotlinx-io) or [Okio](https://square.github.io/okio/) sources and sinks.
You can use these APIs to serialize and deserialize JSON directly from I/O sources without creating intermediate strings.
These APIs use UTF-8 encoding and throw `SerializationException` for invalid JSON data and `IOException` for I/O failures.

> When working with I/O resources, it's important to close them properly to prevent resource leaks.
> You can do this with the `.use()` function, which closes the resource automatically when the operation completes.
Expand Down Expand Up @@ -64,7 +65,7 @@ fun main() {

In this example, the JSON contents of the input stream are deserialized into a single `Project` instance.

If your input contains multiple JSON objects in a top-level JSON array, you can use [`.decodeToSequence()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json/kotlinx.serialization.json/decode-to-sequence.html) to process the elements lazily.
If your input contains multiple JSON objects in a top-level JSON array or as whitespace-separated objects, you can use [`.decodeToSequence()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json/kotlinx.serialization.json/decode-to-sequence.html) to process the elements lazily.
This lets you handle each value as it is parsed.

Here's an example:
Expand Down Expand Up @@ -96,56 +97,54 @@ fun main() {
> You can iterate through sequences returned by `.decodeToSequence()` only once
> because they are tied to the underlying stream.
>
> Closing the stream before the sequence is fully evaluated causes an `IOException`.
>
{style="note"}

## JSON serialization with kotlinx-io and Okio

In addition to JVM streams, you can work with JSON using I/O types, such as `Source` and `Sink` from [`kotlinx-io`](https://github.com/Kotlin/kotlinx-io), and `BufferedSource`
and `BufferedSink` from [Okio](https://square.github.io/okio/).
In addition to JVM streams, you can work with JSON using I/O types, such as `kotlinx.io.Sink` and `kotlinx.io.Source` from [`kotlinx-io`](https://github.com/Kotlin/kotlinx-io) (currently in [Alpha](components-stability.md#stability-levels-explained)), and `okio.BufferedSink`
and `okio.BufferedSource` from [Okio](https://square.github.io/okio/).

You can use the following `Json` extension functions to read and write JSON directly through these I/O types:

* [`.encodeToSink()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-io/kotlinx.serialization.json.io/encode-to-sink.html) and [`.encodeToBufferedSink()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-okio/kotlinx.serialization.json.okio/encode-to-buffered-sink.html) to write JSON to a `Sink` or `BufferedSink`.
* [`.decodeFromSource()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-io/kotlinx.serialization.json.io/decode-from-source.html) and [`.decodeFromBufferedSource()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-okio/kotlinx.serialization.json.okio/decode-from-buffered-source.html) to read a single JSON value from a `Source` or `BufferedSource`.
* [`.encodeToSink()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-io/kotlinx.serialization.json.io/encode-to-sink.html) and [`.encodeToBufferedSink()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-okio/kotlinx.serialization.json.okio/encode-to-buffered-sink.html) to write JSON to a `kotlinx.io.Sink` or `okio.BufferedSink`.
* [`.decodeFromSource()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-io/kotlinx.serialization.json.io/decode-from-source.html) and [`.decodeFromBufferedSource()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-okio/kotlinx.serialization.json.okio/decode-from-buffered-source.html) to read a single JSON value from a `kotlinx.io.Source` or `okio.BufferedSource`.
* [`.decodeSourceToSequence()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-io/kotlinx.serialization.json.io/decode-source-to-sequence.html) and [`.decodeBufferedSourceToSequence()`](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json-okio/kotlinx.serialization.json.okio/decode-buffered-source-to-sequence.html) to lazily decode multiple JSON values as a `Sequence<T>`.

> The JSON I/O extension functions use UTF-8 encoding and throw `SerializationException` for invalid JSON data and `IOException` for I/O failures.
>
{style="tip"}
The next sections cover examples using `kotlinx-io` types with these APIs.
You can use Okio types similarly with their corresponding `okio.BufferedSink` and `okio.BufferedSource`.

To use these extension functions with `kotlinx-io` or Okio types, add the following dependencies to your project:
### Add dependencies for kotlinx-io and Okio

To use the extension functions with `kotlinx-io` or Okio types, add the dependencies you need.

#### Add dependencies for `kotlinx-io` {initial-collapse-state="collapsed" collapsible="true"}

<tabs>
<tab id="kotlin" title="Gradle Kotlin">
<tab id="kotlin-io" title="Gradle Kotlin">

```kotlin
// build.gradle.kts
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-io:%serializationVersion%")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:%serializationVersion%")

implementation("org.jetbrains.kotlinx:kotlinx-io-core:%kotlinxIoVersion%")
implementation("com.squareup.okio:okio:%okioVersion%")
}

```

</tab>
<tab id="groovy" title="Gradle Groovy">
<tab id="groovy-io" title="Gradle Groovy">

```groovy
// build.gradle
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json-io:%serializationVersion%"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json-okio:%serializationVersion%"

implementation "org.jetbrains.kotlinx:kotlinx-io-core:%kotlinxIoVersion%"
implementation "com.squareup.okio:okio:%okioVersion%"
}
```

</tab>
<tab id="maven" title="Maven">
<tab id="maven-io" title="Maven">

```xml
<!-- pom.xml -->
Expand All @@ -157,13 +156,48 @@ dependencies {
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-json-okio</artifactId>
<version>%serializationVersion%</version>
<artifactId>kotlinx-io-core</artifactId>
<version>%kotlinxIoVersion%</version>
</dependency>
</dependencies>
```
</tab>
</tabs>

#### Add dependencies for Okio {initial-collapse-state="collapsed" collapsible="true"}

<tabs>
<tab id="kotlin" title="Gradle Kotlin">

```kotlin
// build.gradle.kts
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:%serializationVersion%")
implementation("com.squareup.okio:okio:%okioVersion%")
}
```

</tab>
<tab id="groovy" title="Gradle Groovy">

```groovy
// build.gradle
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json-okio:%serializationVersion%"
implementation "com.squareup.okio:okio:%okioVersion%"
}
```

</tab>
<tab id="maven" title="Maven">

```xml
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-io-core</artifactId>
<version>%kotlinxIoVersion%</version>
<artifactId>kotlinx-serialization-json-okio</artifactId>
<version>%serializationVersion%</version>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
Expand All @@ -175,10 +209,6 @@ dependencies {
</tab>
</tabs>

The next sections cover examples using `kotlinx-io` types with these APIs.
You can use Okio types similarly with their corresponding `BufferedSource` and `BufferedSink`.


### Serialize JSON to Sinks

Use the `.encodeToSink()` function to serialize JSON to a `Sink`:
Expand Down Expand Up @@ -277,4 +307,47 @@ fun main() {
> You can iterate through sequences returned by `.decodeSourceToSequence()` only once
> because they are tied to the underlying `Source`.
>
> Closing the stream before the sequence is fully evaluated causes an `IOException`.
>
{style="note"}

## Okio

```kotlin
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*

// Imports declarations for Okio types and JSON Okio support
import kotlinx.serialization.json.okio.*
import okio.BufferedSource
import okio.FileSystem
import okio.Path.Companion.toPath
import okio.buffer


@Serializable
data class Project(val name: String, val stars: Int)

@OptIn(ExperimentalSerializationApi::class)
fun main() {
// Opens a BufferedSource for the "projects.json" file containing multiple JSON objects
val path = "projects.json".toPath()
FileSystem.SYSTEM.source(path).buffer().use { source: BufferedSource ->

// Lazily deserializes each Project as it is read from the BufferedSource
val projects: Sequence<Project> = Json.decodeBufferedSourceToSequence(source)

for (project in projects) {
println(project)
}
}
}

```


## What's next

* Explore [advanced JSON element handling](serialization-json-elements.md) to manipulate and work with JSON data before it's parsed or serialized.
* Discover how to [transform JSON during serialization and deserialization](serialization-transform-json.md) for more control over your data.