When using int64 as a struct field, graphql.Int graphql.Float does not work.
I took a look in utils.go it seems not dealing with int64 situation.
I can only make that field as a string, can anyone help me with this ~ thanks~
I imagine the graphql.Float scalar does not accept an int64 because the conversion to a float64 comes with a potential loss of precision because the float can only give an exact representation of ints upto 52 bits wide.
You also can't use a graphql.Int because it's specified as 32bit in the GraphQL Spec.
Basically you have 2 options for representing an int64. First would be implementing a custom GraphQL scalar type that you would use instead of graphql.Int or graphql.String. If you consume your GraphQL API from Javascript, you should be aware though that the JS Number type is also represented by a double precision float, so there would also be a loss of precision for numbers > (2**53)-1.
As you already discovered the second option would be to make that field a string.
You can also write your own Scalar to handle int64 (something that sits in your application). You can look into how Scalars are implemented and provide your own custom type in that regard, enabling this behavior. But as it's not part of the GraphQL spec then I doubt officially supporting it would ever be a goal.
But as @sfriedel brought up, Javascript doesn't support 64 bit numbers either so you still have those issues to work around.
Another option (aside from a raw String) is the ID type, which is designed for ID style values that cannot be represented by other types but shouldn't just be considered "strings." It still is "just a string" which allows the system interpreting the response to decide what to do with it (case it to an int64 or leave it as a string for example). For quick reference here's the relevant spec data on ID.
@sfriedel @bbuck Thanks, guys, very helpful!
Since the data I tried to send is a timestamp, I think it would be OK if I just use string for now, cause javascript can compare string with a number, "123">1 works fine in javascript.
For later improvement, I suppose a timestamp type will just do just fine which does not need to concern about floats.
Actually JavaScript has BigInt data type.
@xamgore It _will_. It's not supported in Edge, IE or Safari right now, it's behind a setting in Firefox as of version 67 meaning Chrome is the only place you can really use it. Sure, you could get a polyfill, but frankly if you're building a generic tool like GraphQL you don't want to push your users onto third-party libraries so that would mean we'd expect GraphQL to provide a 64-bit capable integer storage.
In addition to the lack of support for BigInt right now, the latest June 2018 GraphQL spec only appears to support 32-bit integers now.
The Int scalar type represents a signed 32鈥恇it numeric non鈥恌ractional value.
With a special sidebar for any integer value > 32 bits wide:
Numeric integer values larger than 32鈥恇it should either use String or a custom鈥恉efined Scalar type, as not all platforms and transports support encoding integer numbers larger than 32鈥恇it.
Which lines up with the recommendation to use ID, String or building your own scalar.
Most helpful comment
You can also write your own Scalar to handle
int64(something that sits in your application). You can look into how Scalars are implemented and provide your own custom type in that regard, enabling this behavior. But as it's not part of the GraphQL spec then I doubt officially supporting it would ever be a goal.But as @sfriedel brought up, Javascript doesn't support 64 bit numbers either so you still have those issues to work around.
Another option (aside from a raw String) is the ID type, which is designed for ID style values that cannot be represented by other types but shouldn't just be considered "strings." It still is "just a string" which allows the system interpreting the response to decide what to do with it (case it to an int64 or leave it as a string for example). For quick reference here's the relevant spec data on ID.