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

json-serializer.mddocs/

JSON Serializer Interface

Abstract interface defining the contract for JSON serialization and deserialization in Ktor HTTP clients. Implementations provide specific backends like Gson or Kotlinx Serialization.

Capabilities

JsonSerializer Interface

Core interface that all JSON serializers must implement to provide serialization and deserialization functionality.

/**
 * Client json serializer.
 */
@Deprecated("Please use ContentNegotiation plugin and its converters")
interface JsonSerializer {
    /**
     * Convert data object to OutgoingContent.
     */
    fun write(data: Any, contentType: ContentType): OutgoingContent
    
    /**
     * Convert data object to OutgoingContent using default JSON content type.
     */
    fun write(data: Any): OutgoingContent
    
    /**
     * Read content from response using information specified in type.
     */
    fun read(type: TypeInfo, body: Input): Any
}

Platform Default Serializer

Factory function for obtaining platform-specific default JSON serializer implementations.

/**
 * Platform default serializer.
 * Uses service loader on JVM.
 * Consider adding one of the following dependencies:
 * - ktor-client-gson
 * - ktor-client-json
 */
expect fun defaultSerializer(): JsonSerializer

Content Type Matcher

Interface for matching JSON content types, including variants with +json suffix.

interface ContentTypeMatcher {
    fun contains(contentType: ContentType): Boolean
}

internal class JsonContentTypeMatcher : ContentTypeMatcher {
    override fun contains(contentType: ContentType): Boolean
}

Platform-Specific Implementations

JVM Implementation

On JVM, the default serializer uses Java's ServiceLoader mechanism to discover available JsonSerializer implementations.

// JVM-specific implementation
actual fun defaultSerializer(): JsonSerializer {
    val serializers = ServiceLoader.load(JsonSerializer::class.java).toList()
    
    if (serializers.isEmpty()) {
        error("""Fail to find serializer. Consider adding one of:
             - ktor-client-gson
             - ktor-client-json
             - ktor-client-serialization""")
    }
    
    return serializers.maxByOrNull { it::javaClass.name }!!
}

Service Provider Configuration

Serializer implementations register themselves via Java's ServiceLoader mechanism:

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

io.ktor.client.plugins.gson.GsonSerializer

Usage Examples

Implementing Custom Serializer

import io.ktor.client.plugins.json.*
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.core.*

class MyCustomSerializer : JsonSerializer {
    override fun write(data: Any, contentType: ContentType): OutgoingContent {
        val jsonString = mySerializationLibrary.toJson(data)
        return TextContent(jsonString, contentType)
    }
    
    override fun write(data: Any): OutgoingContent {
        return write(data, ContentType.Application.Json)
    }
    
    override fun read(type: TypeInfo, body: Input): Any {
        val jsonString = body.readText()
        return mySerializationLibrary.fromJson(jsonString, type.reifiedType)
    }
}

Using Default Serializer

val client = HttpClient {
    install(JsonPlugin) {
        // Uses platform default - discovered via ServiceLoader on JVM
        serializer = defaultSerializer()
    }
}

Content Type Matching

// Built-in JSON content type matcher
val matcher = JsonContentTypeMatcher()

// Matches standard JSON
matcher.contains(ContentType.Application.Json) // true

// Matches JSON variants
matcher.contains(ContentType.parse("application/hal+json")) // true
matcher.contains(ContentType.parse("application/vnd.api+json")) // true

// Doesn't match non-JSON types
matcher.contains(ContentType.Text.Plain) // false

Error Handling

try {
    val data = serializer.read(typeInfo, inputStream)
} catch (e: Exception) {
    // Handle serialization errors
    logger.error("Failed to deserialize JSON", e)
}

Implementation Requirements

When implementing JsonSerializer:

  1. Thread Safety: Implementations should be thread-safe as they may be used concurrently
  2. Error Handling: Should throw descriptive exceptions for malformed JSON or type mismatches
  3. Content Type: The write method should respect the provided ContentType parameter
  4. Type Information: The read method must use TypeInfo to deserialize to the correct type
  5. Resource Management: Properly handle Input streams and close resources when needed

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