I had a look at the GraphQL spec.
The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as a String
; however, it is not intended to be human‐readable. While it is often numeric, it should always serialize as a String
.
–?https://facebook.github.io/graphql/April2016/#sec-ID
That answers the question whether it is left to implementation or dictated by the spec, i.e. ID should be always serialized to a String
.
In addition, in the context of an input type, input needs to be coerced into a string. From the spec:
Input Coercion
When expected as an input type, any string (such as "4"
) or integer (such as 4
) input value should be coerced to ID as appropriate for the ID formats a given GraphQL server expects. Any other input value, including float input values (such as 4.0
), must raise a query error indicating an incorrect type.
That leaves me with the original problem.
I have a mysql backend where my PK are integers.
The way I see it, I have these options:
- Start using UUIDs for PKs. However, this has performance implications.
- Ignore the implicit requirement (originating in the relayjs ecosystem) to have the ID unique across the application, and cast IDs to number when possible for internal consumption.
- Hash Encode IDs on the application data layer, e.g. UUID
base64
derived from a concatenation of table name & PK value.
I am going with the latter option. This is also the approach that graphql-relay-js
has adopted via toGlobalId
and fromGlobalId
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…