Migration from apollo android to apollo kotlin (built in adapters issue)

built in scallars do not work properly.

i have this error -

{"errors":[{"message":"GraphQL.Validation.InvalidVariableError: Variable '$amount' is invalid. Unable to convert '8' to 'Decimal'

I think it is possilbe to convert 8 to BigDecimal(“8”)

is there any solution or just use my own adapter ?

Hi :wave:

That’s interesting. Looks like this message is coming from your backend. I’m not sure why it wouldn’t be able to convert ‘8’ to ‘Decimal’ :thinking:.

Did it use to work? If you can get a proxy or another way to look at the HTTP request, it’d be interesting to look at the sent variables see if there are any differences (maybe it used to send ‘8.0’ before?).

I check, sended variable is “8” like this, when i investigate the problem can be solved from client side by two ways

  1. use old Custom adapter
override fun encode(value: BigDecimal): CustomTypeValue<*> {
        return CustomTypeValue.GraphQLNumber(value)
    }

or another option is new adapter for BigDecimal like this

    override fun toJson(
        writer: JsonWriter,
        customScalarAdapters: CustomScalarAdapters,
        value: BigDecimal
    ) {
        writer.value(JsonNumber(value.toString()))
    }

standart build in BigDecimal adapter do not work because it works it like string which cannot be mapped as Decimal in the backend i dont know exact reason but server side uses .net core where this Decimal is built in class which cannot be parsed from the string

so far what is find out is the problem comes from that

it can parses only from int or float

is it good idea to register an issue in graphql.net framework ?

Hi :wave:

Thanks for the details!

There is no specification for Decimal scalar in GraphQL so there is no definitive answer but in that case I would err on the side that this is an Apollo issue more than a graphql.net one.

It makes sense to expect the decimal as a JSON number and not a JSON string. I made a fix there: Encode BigDecimal as JSON number by martinbonnin · Pull Request #18 · apollographql/apollo-kotlin-adapters · GitHub

Until the next release, you can define your own adapter as you found out:

object BigDecimalAdapter : Adapter<BigDecimal> {
  override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): BigDecimal {
    return BigDecimal(reader.nextString()!!)
  }

  override fun toJson(writer: JsonWriter, customScalarAdapters: CustomScalarAdapters, value: BigDecimal) {
    writer.value(JsonNumber(value.toString()))
  }
}