Skip to main content
Version: 4.x.x

Scalars

Primitive Types

graphql-kotlin-schema-generator can directly map most Kotlin "primitive" types to standard GraphQL scalar types or extended scalar types provided by graphql-java.

Kotlin TypeGraphQL Type
kotlin.StringString
kotlin.BooleanBoolean
kotlin.IntInt
kotlin.DoubleFloat
kotlin.FloatFloat
note

The GraphQL spec uses the term Float for signed double‐precision fractional values. graphql-java maps this to a java.lang.Double for the execution. The generator will map both kotlin.Double and kotlin.Float to GraphQL Float but we reccomend you use kotlin.Double

caution

Extended GraphQL scalar types provided by graphql-java were deprecated in v15. This includes the following types: Long, Short, BigInteger, BigDecimal, and Char. If you are currently using these types, they will be removed in future graphql-java releases.

See the graphql-java-extended-scalars project if you need continued support.

GraphQL ID

GraphQL supports the scalar type ID, a unique identifier that is not intended to be human readable. IDs are serialized as a String. To expose a GraphQL ID field, you must use the com.expediagroup.graphql.generator.scalars.ID class, which wraps the underlying String value.

note

graphql-java supports additional types (String, Int, Long, or UUID) but due to serialization issues we can only directly support Strings. You can still use a type like UUID internally just as long as you convert or parse the value yourself and handle the errors.

data class Person(
val id: ID,
val name: String
)

fun findPersonById(id: ID) = Person(id, "John Smith")

fun generateRandomId(): ID = ID(UUID.randomUUID().toString())

This would produce the following schema:

schema {
query: Query
}

type Query {
findPersonById(id: ID!): Person!
generateRandomId: ID!
}

type Person {
id: ID!
name: String!
}

Custom Scalars

By default, graphql-kotlin-schema-generator uses Kotlin reflections to generate all schema objects. If you want to apply custom behavior to the objects, you can also define your own custom scalars. Custom scalars have to be explicitly added to the schema through SchemaGeneratorHooks.willGenerateGraphQLType. See the Generator Configuration documentation for more information.

Example usage

class CustomSchemaGeneratorHooks : SchemaGeneratorHooks {

override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) {
UUID::class -> graphqlUUIDType
else -> null
}
}

val graphqlUUIDType = GraphQLScalarType.newScalar()
.name("UUID")
.description("A type representing a formatted java.util.UUID")
.coercing(UUIDCoercing)
.build()

object UUIDCoercing : Coercing<UUID, String> {
override fun parseValue(input: Any?): UUID = UUID.fromString(serialize(input))

override fun parseLiteral(input: Any?): UUID? {
val uuidString = (input as? StringValue)?.value
return UUID.fromString(uuidString)
}

override fun serialize(dataFetcherResult: Any?): String = dataFetcherResult.toString()
}

Once the scalars are registered you can use them anywhere in the schema as regular objects.

Common Issues

Extended Scalars

By default, graphql-kotlin only supports the primitive scalar types listed above. If you are looking to use common java types as scalars, you need to include the graphql-java-extended-scalars library and set up the hooks (see above), or write the logic yourself for how to resolve these custom scalars.

The most popular types that require extra configuration are: LocalDate, DateTime, Instant, ZonedDateTime, URL, UUID

TypeNotSupportedException

If you see the following message Cannot convert ** since it is not a valid GraphQL type or outside the supported packages ***. This means that you need to update the generator configuration to include the package of your type or you did not properly set up the hooks to register the new type.