You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using gradle plugin id("com.expediagroup.graphql") version "3.4.2" and implementation("com.expediagroup:graphql-kotlin-client:3.4.2"), kotlin 1.3.72, jackson 2.11.0
Our graphql schema contains types UUID, Long, BigDecimal. UUID, Long can be handled as is shown in example. But this approach does not work for me in case of BigDecimal (I don`t get why it works for Long).
Converters
import java.math.BigDecimal
class LongScalarConverter : ScalarConverter<Long> {
override fun toScalar(rawValue: String): Long = rawValue.toLong()
override fun toJson(value: Long): String = value.toString()
}
class BigDecimalScalarConverter : ScalarConverter<BigDecimal> {
override fun toScalar(rawValue: String): BigDecimal = BigDecimal(rawValue)
override fun toJson(value: BigDecimal): String = value.toString()
}
Generated classes for those registered converters
/**
* Long
*/
data class Long(
val value: kotlin.Long
) {
@JsonValue
fun rawValue() = converter.toJson(value)
companion object {
val converter: LongScalarConverter = LongScalarConverter()
@JsonCreator
@JvmStatic
fun create(rawValue: String) = Long(converter.toScalar(rawValue))
}
}
/**
* BigDecimal
*/
data class BigDecimal(
val value: java.math.BigDecimal
) {
@JsonValue
fun rawValue() = converter.toJson(value)
companion object {
val converter: BigDecimalScalarConverter = BigDecimalScalarConverter()
@JsonCreator
@JvmStatic
fun create(rawValue: String) = BigDecimal(converter.toScalar(rawValue))
}
}
fail with exception
val objectMapper = jacksonObjectMapper()
val inJson = """
0
""".trimIndent()
//works
val longRes = objectMapper.readValue(inJson, CreateCardMutation.Long::class.java)
//works
val javaBigDecimal = objectMapper.readValue(inJson, BigDecimal::class.java)
// this one throw ex
val bigDecimalRes = objectMapper.readValue(inJson, CreateCardMutation.BigDecimal::class.java)
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `SomeMutation$BigDecimal` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (0)
at [Source: (String)"0"; line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1455)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1081)
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:262)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:356)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1359)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:178)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:166)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3402)
at ApplicationKt.main(Application.kt:23)
Works fine with changed generated class to
data class BigDecimal(
val value: java.math.BigDecimal
) {
@JsonCreator
constructor(rawValue: Int) : this(java.math.BigDecimal(rawValue))
}
Any ideas why Long works and BigDecimal not?
Edit: Older jackson versions 2.9.10 throw different ex
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `SomeMutation$BigDecimal` (no Creators, like default constructor, exist): no int/Int-argument constructor/factory method to deserialize from Number value (0)
at [Source: (String)"0"; line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1615)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1077)
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:262)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:356)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1359)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:178)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:166)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3402)
at ApplicationKt.main(Application.kt:26)
The text was updated successfully, but these errors were encountered:
Scalar converter signature accepts Strings as custom GraphQL scalars are serialized as Strings. I just run the example with BigDecimal and it seems to work fine
It works, because server does send BigDecimal as String in provided example.
Is there official GraphQL documentation, which state, than Custom Scalar MUST be serialized as String? We do use on server side other framework, which use jackson ObjectMapper for mapping responses and BigDecimal/Long is serialized as number which is I would say correct behaviour.
In this doc is send timestamp as number marked as custom scalar. I have not found better documentation source about custom scalars.
I was looking through the spec (https://spec.graphql.org/June2018/#sec-Scalars) and indeed it just specifies that scalars are representable as String but doesn't specify that they have to be serialized as String (as opposed to Number, etc). I'll update the ScalarConverter to use Any instead of a String.
Uh oh!
There was an error while loading. Please reload this page.
Hello,
Using gradle plugin
id("com.expediagroup.graphql") version "3.4.2"
andimplementation("com.expediagroup:graphql-kotlin-client:3.4.2")
, kotlin 1.3.72, jackson 2.11.0Our graphql schema contains types UUID, Long, BigDecimal. UUID, Long can be handled as is shown in example. But this approach does not work for me in case of BigDecimal (I don`t get why it works for Long).
Converters
Generated classes for those registered converters
fail with exception
Works fine with changed generated class to
Any ideas why Long works and BigDecimal not?
Edit: Older jackson versions 2.9.10 throw different ex
The text was updated successfully, but these errors were encountered: