For a type like this in the schema ```type Money {...
# apollo-kotlin
s
For a type like this in the schema
Copy code
type Money {
    amount: Float!
    "Currency of the money (ISO 4217)."
    currencyCode: CurrencyCode!
}
If this were a scalar, I would know how to make an adapter so that in code I can always use some more apt money type (if you have suggestions here for a good Money library, only to represent it, not to do maths on the client, open to hear about it) Since it’s just a type, it will by default generate a Kotlin object which is gonna represent
amount
as a
Float
. Is there a way for me to change that so I never see the
amount
as a float in the first place?
m
You could patch your schema and define your scalar type client side. It's a bit hacky but that'd work
schema.writeText(schema.readText().replace("Money", "CustomMoney"))
and then
Copy code
#extra.graphqls
scalar CustomMoney
s
Aha! And then I can make my adapter take in the value and read it as a float (as that’s what it really is), and convert it to CustomMoney just as I normally would if it was a scalar in the first place
m
I think that'd work
It'd have cache implications though because it means there's no
__typename
anymore
All the
CustomMoney
would be embedded in their parent record
Which is certainly fine for this specific case but probably not in more complex ones
s
Yeah makes sense for caching, I think this will be fine for our case. I am discussing basically this type with some backenders and I really don’t want to have a float for money so I am exploring what options I have on my end to at least make my life easier. So can’t test atm, but when the time comes I will need to check out how to do this So the follow-up questions: • Does a Float look fine in this context? My intuition tells me it’s odd to represent it as a Float on the schema, but I may be over-reacting since we’re not gonna be performing any actual calculations client-side • Do you actually have some favourite Money library for jvm/Kotlin? Just if you’ve happened to work with money related things before.
m
Isn't the usual thing with Money that you want bigint or anything to avoid loosing (or winning) money due to rounding errors?
If that's only for display, I'd be fine with
Float
Also note that GraphQL
Float
is Kotlin
Double
for some reason so it's 64 bits
s
Yeah definitely, I think on the backend it is BigSomething, but then only when handed off to the clients it’s translated to Float, supposedly since the web clients had an easier time with it this way. That’s what I understood. Ah good to know about the double, thanks! I will probably need this information when I have to build the adapter.
m
on the backend it is BigSomething, but then only when handed off to the clients it’s translated to Float, supposedly since the web clients had an easier time with it this way. That’s what I understood.
Sounds like a reasonable approach 👍
b
I'd recommend using strings on the wire
Floats usually bring precision issues, ints have a max value. Strings can be converted to a BigInteger on the client.
m
I'm team 'Float', it makes it explicit that it's not for computations but for display (if that is what it really is)
I wish my bank would give me monthly report with BitDecimal accuracy though 😄
I wish my bank had an API lol
b
isn't String even more explicit about it being for display? 🙂
m
Yea I guess so, if it were for computation, I'd expect a custom scalar
But some clients might still want to tune the displayed precision in which case Float is better
Like do you need a coma or a dot
I wish Excel stopped using comas!
I wish a lot of things!
b
I think I would go with a custom scalar with the amount being "cents" represented as Strings [some currencies don't have cents]. But yeah... "it depends" 😄 Not an obvious topic actually.
s
But some clients might still want to tune the displayed precision in which case Float is better
Shouldn’t a client anyway be taking this Float, turning it into [Insert favorite Money type here, let’s call it CustomMoney] and use the formatter that it provides anyway, so that it will be respecting current locale etc. to know how to represent this in the UI. So whether the input to [CustomMoney] is a Float, or a String doesn’t matter for the client, since it should be able to handle both (As I understand, BigDecimal can handle both for the JVM for example) and the only thing one is doing by sending a Float over the wire is potentially losing some precision?
m
Losing precision and also losing network bytes
But yea, in all cases it should be formatted
s
Losing precision and also losing network bytes
So are you team String now too? 😂
m
Nope, losing network bytes is a good thign
(in that case 🙂 )
s
Oh, losing, as in less, not "losing space" aka taking up more space 💀
m
yep!
Sorry that wasn't clear, it's more "trimming" than "losing"
Because we don't care it's lost
I'm team Float or scalar with fixed precision like @bod hinted at before (with cents)
s
Seems like today every discussion I’m having I always turn out to be wrong about stuff 😅 But hey, the more you know! Thanks for the help and the discussion 🤗