KotlinxGraphQLJson

class KotlinxGraphQLJson(json: Json = Json { ignoreUnknownKeys = true }) : GraphQLJson(source)

Deprecated

Legacy GraphQLJson implementation of the GraphConverter flow. Use KotlinxGraphQLTransportCodec with the backend-neutral GraphQLConverterFactory instead.

kotlinx.serialization-backed implementation of GraphQLJson.

Legacy: lives in :compat for the deprecated co.anitrend.retrofit.graphql.converter.GraphConverter flow. New code should use co.anitrend.retrofit.graphql.serialization.kotlinx.KotlinxGraphQLTransportCodec from :serialization-kotlinx with the backend-neutral co.anitrend.retrofit.graphql.converter.GraphQLConverterFactory.

Parameterized Type Handling

Uses kotlinx.serialization.serializer with java.lang.reflect.Type overload to handle parameterized types (e.g. GraphContainer<GetCurrentUserData>, List<Bar>) provided by Retrofit's converter infrastructure. This is the key difference from a naive serializer<T>() call: Retrofit passes a java.lang.reflect.ParameterizedType, and the JVM reflection extension serializer(type) resolves the correct KSerializer for the full type.

Usage

val json = KotlinxGraphQLJson(
Json {
ignoreUnknownKeys = true
encodeDefaults = false
}
)
val converter = GraphConverter.create(
context = context,
json = json,
registry = GeneratedGraphQLRegistry,
)

Plain empty variables sentinel

EmptyGraphQLVariables is a plain marker object in :api and carries no serializer annotation. When a GraphQLRequest<EmptyGraphQLVariables> is encoded, no KSerializer exists for the sentinel, so encode special-cases it: the sentinel encodes as an empty JSON object {}, and a null variables value keeps the pre-existing omission behavior. This keeps the legacy typed request flow working without reintroducing a serializer dependency into :api.

Limitations

  • GraphContainer.extensions remains @Transient because its Map<Any, Any> type cannot be statically resolved.

  • GraphQLRequest.extensions remains @Transient on the data class, but encode merges supported extension values into the encoded JSON at runtime so withPersistedQuery() still works for the typed request flow.

  • GraphError.path and GraphError.extensions are @Transient for the same reason.

  • QueryContainer is not @Serializable; the runtime keeps the legacy QueryContainerBuilder request flow on a Gson-backed serializer.

Working Around @Transient Fields

When you need access to @Transient fields with kotlinx, define complete transport wrapper classes that include those fields with concrete types that kotlinx can resolve (e.g. JsonObject instead of Map<Any, Any>):

@Serializable
data class JsonGraphContainer<T>(
val data: T? = null,
val errors: List<JsonGraphError>? = null,
val extensions: JsonObject? = null,
)

@Serializable
data class JsonGraphError(
val message: String? = null,
val path: List<JsonElement>? = null,
val locations: List<GraphError.Location>? = null,
val extensions: JsonObject? = null,
)

Then use the wrapper as the Retrofit response type:

@POST("graphql")
suspend fun getCurrentUser(
@Body request: GraphQLRequest<EmptyGraphQLVariables>,
): Response<JsonGraphContainer<GetCurrentUserData>>

Use a custom serializer only when the wire JSON shape itself needs to be transformed before or after normal serialization. For detailed per-type examples, see the KDoc on GraphContainer.extensions, GraphError.path, GraphError.extensions, and GraphQLRequest.extensions.

Parameters

json

A configured Json instance. Defaults to Json with Json.ignoreUnknownKeys enabled so that fields not present in the generated data class are silently skipped.

See also

GsonGraphQLJson
co.anitrend.retrofit.graphql.serialization.kotlinx.KotlinxGraphQLTransportCodec

Constructors

Link copied to clipboard
constructor(json: Json = Json { ignoreUnknownKeys = true })

Functions

Link copied to clipboard
open override fun <T : Any> decode(jsonStr: String, type: Type): T

Decode a JSON string into an instance of T.

Link copied to clipboard
open override fun <T : Any> encode(value: T, type: Type? = null): String

Encode value into a JSON string.