https://kotlinlang.org logo
#graphql-kotlin
Title
# graphql-kotlin
s

S.

11/12/2023, 12:00 AM
Copy code
All types within a GraphQL schema must have unique names. No two provided types may have the same name.
No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).
You have redefined the type 'LocalDateTime' from being a 'GraphQLScalarType' to a 'GraphQLScalarType'
Copy code
class CustomSchemaGeneratorHooks : SchemaGeneratorHooks {
    override fun willGenerateGraphQLType(type: KType): graphql.schema.GraphQLType? =
        when (type.classifier as? KClass<*>) {
            UUID::class -> CustomGraphQLScalar.graphqlUUID
            LocalDateTime::class -> CustomGraphQLScalar.graphqlLocalDateTime

            else -> null
        }
}

val CustomGraphQLScalar.graphqlLocalDateTime: GraphQLScalarType
    get() = GraphQLScalarType.newScalar()
        .name("LocalDateTime")
        .description("A type representing a formatted kotlinx.datetime.LocalDateTime")
        .coercing(LocalDateTimeCoercing)
        .build()

private object LocalDateTimeCoercing : Coercing<LocalDateTime, String> {
    override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): LocalDateTime = runCatching {
        LocalDateTime.parse(serialize(input, graphQLContext, locale))
    }.getOrElse {
        throw CoercingParseValueException("Expected valid LocalDateTime but was $input")
    }

    override fun parseLiteral(
        input: Value<*>,
        variables: CoercedVariables,
        graphQLContext: GraphQLContext,
        locale: Locale,
    ): LocalDateTime {
        val localDateTimeString = (input as? StringValue)?.value
        return runCatching {
            LocalDateTime.parse(localDateTimeString!!)
        }.getOrElse {
            throw CoercingParseValueException("Expected valid LocalDateTime literal but was $localDateTimeString")
        }
    }

    override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
        runCatching {
            dataFetcherResult.toString()
        }.getOrElse {
            throw CoercingParseValueException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
        }
}
what does cause this
You have redefined the type 'LocalDateTime' from being a 'GraphQLScalarType' to a 'GraphQLScalarType'
error?
d

Dariusz Kuc

11/12/2023, 2:40 AM
👋 pretty sure you are hitting this bug -> https://github.com/ExpediaGroup/graphql-kotlin/issues/1815
The issue is that you are creating the
graphqlLocalDateTime
twice (guessing it is referenced from two different places) and as a result
graphql-java
see two different objects (as they dont implement hashcode/equals) Workaround/fix is to drop
get()
and just declare the scalar as val (as otherwise you are constructing new scalar whenever referencing it)
s

S.

11/12/2023, 11:24 AM
interesting. but yes, that fixed it. thank you!