CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-json-jvm

JSON serialization plugin for Ktor HTTP client (JVM platform)

Pending
Overview
Eval results
Files

kotlinx-serializer.mddocs/

Kotlinx Serialization

Kotlinx Serialization-based JSON implementation for Ktor HTTP clients. Provides compile-time safe serialization with advanced features like polymorphism, custom serializers, and contextual serialization.

Capabilities

KotlinxSerializer Class

JsonSerializer implementation using kotlinx.serialization library for JSON processing.

/**
 * A JsonSerializer implemented for kotlinx Serializable classes.
 */
@Deprecated("Please use ContentNegotiation plugin and its converters")
class KotlinxSerializer(private val json: Json = DefaultJson) : JsonSerializer {
    /**
     * Convert data object to OutgoingContent using kotlinx.serialization.
     */
    override fun write(data: Any, contentType: ContentType): OutgoingContent
    
    /**
     * Read content from response using kotlinx.serialization deserialization.
     */
    override fun read(type: TypeInfo, body: Input): Any
    
    /**
     * Internal method for content serialization.
     */
    internal fun writeContent(data: Any): String
    
    companion object {
        /**
         * Default Json configuration for KotlinxSerializer.
         */
        val DefaultJson: Json
    }
}

Default Json Configuration

Preconfigured Json instance with sensible defaults for HTTP client usage.

val DefaultJson: Json = Json {
    isLenient = false
    ignoreUnknownKeys = false
    allowSpecialFloatingPointValues = true
    useArrayPolymorphism = false
}

Service Registration

The KotlinxSerializer is automatically discoverable on JVM through the ServiceLoader mechanism:

META-INF/services/io.ktor.client.plugins.json.JsonSerializer

io.ktor.client.plugins.kotlinx.serializer.KotlinxSerializer

Dependencies

To use KotlinxSerializer, add the kotlinx.serialization dependency:

Gradle

implementation("io.ktor:ktor-client-serialization:2.3.13")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")

Maven

<dependency>
    <groupId>io.ktor</groupId>
    <artifactId>ktor-client-serialization-jvm</artifactId>
    <version>2.3.13</version>
</dependency>

Usage Examples

Basic Usage

import io.ktor.client.*
import io.ktor.client.plugins.json.*
import io.ktor.client.plugins.kotlinx.serializer.*
import kotlinx.serialization.*

val client = HttpClient {
    install(JsonPlugin) {
        serializer = KotlinxSerializer()
    }
}

Custom Json Configuration

import kotlinx.serialization.json.*

val client = HttpClient {
    install(JsonPlugin) {
        serializer = KotlinxSerializer(Json {
            prettyPrint = true
            isLenient = true
            ignoreUnknownKeys = true
            coerceInputValues = true
            useAlternativeNames = false
            namingStrategy = JsonNamingStrategy.SnakeCase
            explicitNulls = false
        })
    }
}

Serializable Data Classes

import kotlinx.serialization.*

@Serializable
data class User(
    val id: Long,
    val name: String,
    val email: String,
    @SerialName("created_at")
    val createdAt: String
)

// POST request - automatic serialization
val response = client.post("https://api.example.com/users") {
    contentType(ContentType.Application.Json)
    setBody(User(0, "Alice", "alice@example.com", "2023-01-01"))
}

// GET request - automatic deserialization
val user: User = client.get("https://api.example.com/users/1").body()

Polymorphic Serialization

@Serializable
sealed class Animal {
    abstract val name: String
}

@Serializable
@SerialName("dog")
data class Dog(
    override val name: String,
    val breed: String
) : Animal()

@Serializable  
@SerialName("cat")
data class Cat(
    override val name: String,
    val color: String
) : Animal()

// Usage
val animals: List<Animal> = listOf(
    Dog("Buddy", "Golden Retriever"),
    Cat("Whiskers", "Orange")
)

val response = client.post("https://api.example.com/animals") {
    contentType(ContentType.Application.Json)
    setBody(animals)
}

Custom Serializers

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

@Serializer(forClass = LocalDateTime::class)
object LocalDateTimeSerializer : KSerializer<LocalDateTime> {
    private val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
    
    override val descriptor: SerialDescriptor = 
        PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
    
    override fun serialize(encoder: Encoder, value: LocalDateTime) {
        encoder.encodeString(value.format(formatter))
    }
    
    override fun deserialize(decoder: Decoder): LocalDateTime {
        return LocalDateTime.parse(decoder.decodeString(), formatter)
    }
}

@Serializable
data class Event(
    val id: Long,
    val name: String,
    @Serializable(with = LocalDateTimeSerializer::class)
    val timestamp: LocalDateTime
)

Contextual Serialization

// Define contextual serializer
val module = SerializersModule {
    contextual(LocalDateTime::class, LocalDateTimeSerializer)
}

val client = HttpClient {
    install(JsonPlugin) {
        serializer = KotlinxSerializer(Json {
            serializersModule = module
        })
    }
}

@Serializable
data class Event(
    val id: Long, 
    val name: String,
    @Contextual
    val timestamp: LocalDateTime
)

Collection Handling

// List serialization
@Serializable
data class UserList(val users: List<User>)

// Map serialization  
@Serializable
data class UserMap(val users: Map<String, User>)

// Direct collection serialization
val users: List<User> = client.get("https://api.example.com/users").body()
val userMap: Map<String, User> = client.get("https://api.example.com/users/map").body()

Error Handling

import kotlinx.serialization.*

try {
    val user: User = client.get("https://api.example.com/users/1").body()
} catch (e: SerializationException) {
    // Serialization/deserialization error
    logger.error("JSON serialization error", e)
} catch (e: MissingFieldException) {
    // Required field missing
    logger.error("Missing required field", e)
} catch (e: UnknownKeyException) {
    // Unknown key in JSON (when ignoreUnknownKeys = false)
    logger.error("Unknown JSON key", e)
}

Advanced Configuration

val client = HttpClient {
    install(JsonPlugin) {
        serializer = KotlinxSerializer(Json {
            // Parsing options
            isLenient = true                    // Allow lenient parsing
            ignoreUnknownKeys = true           // Ignore unknown JSON keys
            coerceInputValues = true           // Coerce invalid values to defaults
            
            // Output options  
            prettyPrint = true                 // Pretty print JSON
            prettyPrintIndent = "  "          // Custom indent
            
            // Null handling
            explicitNulls = false             // Don't encode null values
            
            // Naming strategy
            namingStrategy = JsonNamingStrategy.SnakeCase
            
            // Special values
            allowSpecialFloatingPointValues = true  // Allow NaN, Infinity
            allowStructuredMapKeys = true           // Allow complex map keys
            
            // Polymorphism
            useArrayPolymorphism = false            // Use object polymorphism
            
            // Custom serializers module
            serializersModule = SerializersModule {
                contextual(LocalDateTime::class, LocalDateTimeSerializer)
                polymorphic(Animal::class) {
                    subclass(Dog::class)
                    subclass(Cat::class)
                }
            }
        })
    }
}

Json Configuration Options

The KotlinxSerializer supports extensive Json configuration:

Parsing Options

  • isLenient: Allow lenient JSON parsing
  • ignoreUnknownKeys: Ignore unknown properties
  • coerceInputValues: Coerce invalid input to defaults
  • allowStructuredMapKeys: Allow non-primitive map keys
  • allowSpecialFloatingPointValues: Allow NaN and Infinity

Output Options

  • prettyPrint: Enable pretty printing
  • prettyPrintIndent: Custom indentation string
  • explicitNulls: Control null value encoding

Advanced Features

  • serializersModule: Custom serializers and polymorphism
  • namingStrategy: Field naming strategy
  • useArrayPolymorphism: Polymorphism format choice

Performance Considerations

  • Json instances are thread-safe and should be reused
  • Contextual serializers are resolved at runtime
  • Use @Serializable annotation for compile-time code generation
  • Consider using sealed classes for polymorphic hierarchies
  • Custom serializers should be lightweight and stateless

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-json-jvm

docs

gson-serializer.md

index.md

jackson-serializer.md

json-plugin.md

json-serializer.md

kotlinx-serializer.md

tile.json