GraphQLSwift / Graphiti

The Swift GraphQL Schema framework for macOS and Linux
MIT License
531 stars 67 forks source link

Decimal and NSDecimal #121

Open ZirgVoice opened 1 year ago

ZirgVoice commented 1 year ago

I use Decimal type, on Linux it is Decimal in the schema, but when running on macOS it is NSDecimal in the schema. Is it possible to fix this so that it would be Decimal regardless of the operating system?

NeedleInAJayStack commented 1 year ago

Hi @ZirgVoice, could you provide a code snippet that demonstrates how you're using Decimal? If you can give me something that would give warnings or errors, that'd be bonus points! I see that this package and GraphQL do use Decimal and NSDecimal in different places, but it's a little hard for me to figure out what you're trying to do.

Thanks!

ZirgVoice commented 1 year ago

I will use this type as an input argument to create the transaction.

struct CreateTransaction: Codable {
    var fee: Decimal
    var userID: ID?
    ...
}

class TransactionSchema: PartialSchema<GraphQLResolver, Context> {
    @TypeDefinitions
    override var types: Types {
        Scalar(Decimal.self)
    }
}

Since I'm using gateway and federation, I add to the sdl

scalar Decimal

extend type Mutation {
    createTransaction(
        fee: Decimal!
        userID: ID
        ...
    ): Transaction!
...
}

If we don't use the gateway, NSDecimal doesn't cause any problems, on macOS it is displayed in the schema as NSDecimal type, and in Linux it is Decimal. But the gateway takes the schema from sdl and accordingly sets the fee field to Decimal type, again on Linux there are no problems with this, on macOS the payment service is waiting for NSDecimal type and the gateway sends it Decimal type, so I get a type mismatch error. Having written in sdl scalar NSDecimal, the gateway uses it and everything works on macOS.

NeedleInAJayStack commented 1 year ago

Hmm, the short-term workaround is probably to use a Double in place of Decimal, which is definitely the more typical usage (and built-in for GraphQL Float type). Another alternative could be to write custom serialize, parseValue, and parseLiteral functions for your scalar using the initializer introduced in this recent MR. And then finally there's the option of fixing the underlying issue in the GraphQL repo itself, which is a bit complex because NSDecimal is (as far as I've investigated) used to efficiently decode using NSObject.