-
Notifications
You must be signed in to change notification settings - Fork 4
Gradle GraphQL Scalar Mapping
To generate client DSL from our GraphQL schema, we have to provide mapping of scalars, defined in the schema, to Kotlin data types.
Kobby provides default mapping for some scalars:
GraphQL Scalar | Kotlin Type |
---|---|
ID | kotlin.Long |
Int | kotlin.Int |
Long | kotlin.Long |
Float | kotlin.Double |
Double | kotlin.Double |
String | kotlin.String |
Boolean | kotlin.Boolean |
You can configure your own mapping or override default mapping by means of kobby.kotlin.scalars
property:
kobby {
kotlin {
scalars = mapOf(
"ID" to typeOf("java.util", "UUID"),
"Date" to typeOf("java.time", "LocalDate")
)
}
}
The scalars
property is of type Map<String, KotlinType>
, where key of the map is name of GraphQL scalar and value of
the map is Kobby KotlinType
:
package io.github.ermadmi78.kobby.generator.kotlin
class KotlinType(
/** A fully-qualified package name. For example: kotlin.collections */
val packageName: String,
/** A fully-qualified class name. For example: Map.Entry */
val className: String,
val allowNull: Boolean = false,
/** List of generics */
val generics: List<KotlinType> = listOf()
) {
fun nullable(): KotlinType =
if (allowNull) this else KotlinType(packageName, className, true, generics)
fun parameterize(vararg arguments: KotlinType): KotlinType =
if (arguments.isEmpty()) this else KotlinType(packageName, className, allowNull, generics + arguments)
fun nested(nestedClassName: String): KotlinType =
KotlinType(packageName, "$className.$nestedClassName", allowNull, generics)
}
To simplify KotlinType
creation, Kobby extension provides builder functions:
package io.github.ermadmi78.kobby
fun typeOf(packageName: String, className: String, vararg arguments: KotlinType) =
KotlinType(packageName, className, false, arguments.toList())
fun typeOf(packageName: String, className: String, nullable: Boolean, vararg arguments: KotlinType) =
KotlinType(packageName, className, nullable, arguments.toList())
For example, let configure Map<String, Any?>
type for JSON
scalar:
import io.github.ermadmi78.kobby.kobby
kobby {
kotlin {
scalars = mapOf(
"JSON" to typeOf(
"kotlin.collections", "Map",
typeOf("kotlin", "String"),
typeOf("kotlin", "Any", nullable = true)
)
)
}
}
Let simplify our example by means of parameterize
and nullable
functions:
import io.github.ermadmi78.kobby.kobby
kobby {
kotlin {
scalars = mapOf(
"JSON" to typeOf("kotlin.collections", "Map").parameterize(
typeOf("kotlin", "String"),
typeOf("kotlin", "Any").nullable()
)
)
}
}
The Kobby extension provides a set of predefined constants for standard Kotlin types. With the help of constants, we can rewrite our example like this:
import io.github.ermadmi78.kobby.kobby
kobby {
kotlin {
scalars = mapOf(
"JSON" to typeMap.parameterize(typeString, typeAny.nullable())
)
}
}
All available constants:
Constant | Kotlin Type |
---|---|
typeAny | kotlin.Any |
typeNumber | kotlin.Number |
typeByte | kotlin.Byte |
typeShort | kotlin.Short |
typeInt | kotlin.Int |
typeLong | kotlin.Long |
typeFloat | kotlin.Float |
typeDouble | kotlin.Double |
typeChar | kotlin.Char |
typeString | kotlin.String |
typeCharSequence | kotlin.CharSequence |
typeBoolean | kotlin.Boolean |
typeEnum | kotlin.Enum |
typeThrowable | kotlin.Throwable |
typeComparable | kotlin.Comparable |
typeIterable | kotlin.collections.Iterable |
typeCollection | kotlin.collections.Collection |
typeList | kotlin.collections.List |
typeSet | kotlin.collections.Set |
typeMap | kotlin.collections.Map |
typeMutableIterable | kotlin.collections.MutableIterable |
typeMutableCollection | kotlin.collections.MutableCollection |
typeMutableList | kotlin.collections.MutableList |
typeMutableSet | kotlin.collections.MutableSet |
typeMutableMap | kotlin.collections.MutableMap |
typeArray | kotlin.Array |
typeBooleanArray | kotlin.BooleanArray |
typeByteArray | kotlin.ByteArray |
typeCharArray | kotlin.CharArray |
typeShortArray | kotlin.ShortArray |
typeIntArray | kotlin.IntArray |
typeLongArray | kotlin.LongArray |
typeFloatArray | kotlin.FloatArray |
typeDoubleArray | kotlin.DoubleArray |
You can configure a custom serializer to any type associated with a scalar (see Kotlinx Serialization support):
kobby {
kotlin {
scalars = mapOf(
"Date" to typeOf("java.time", "LocalDate")
.serializer(
"io.github.ermadmi78.kobby.cinema.api.kobby.kotlin.dto", // package name
"LocalDateSerializer" // class name
)
)
}
}