Graphql ID resolves as string even if it’s integer

Graphql ID resolves as string even if it’s integer


1

I’m new to graphql and hope someone can explain me this ID type that is always string.

As said in the docs:

The ID scalar type represents a unique identifier, often used to re-fetch an object or as a key for a cache.

If you use, for example, some caching client like Apollo, each type
should have at least one ID. This allows us to perform a normalization
of queries, making it possible for us to update things in Apollo
internal redux store automatically based on the unique id

Ok, so I can use Int, but how then I get my id as an integer on the client side?

My reason is simple: let’s say I have Book type with id of type ID and author_id relation of type Int. Also, I have an Author custom scalar defined with an id property of type ID. After I fetch the book and author, I will have book.author_id of type int and author.id of type string, but it’s the same number!

What should I do? Use the ID type everywhere even though there’s many to many relations? Or, should I make a new scalar using ID as the type that can be used as the ID for re-fetch; but will be of type Int?

Share
Improve this question

1

  • That doesn't appear to be from any official docs, just some article. And an old one at that since Apollo client hasn't used redux since version 2.0.

    – Daniel Rearden

    Jan 24, 2020 at 20:38

2 Answers
2

Reset to default


2

From the spec:

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… GraphQL is agnostic to ID format, and serializes to string to ensure consistency across many formats ID could represent, from small auto‐increment numbers, to large 128‐bit random numbers, to base64 encoded values, or string values of a format like GUID.

It’s unclear why the client would care about comparing IDs in this context — columns like author_id should generally be hidden from the client anyway, with the schema only exposing the related entity, not fields that are only used to link entities. That said, an ID is just an ID and a client shouldn’t care whether it’s a string or an integer as long as it’s consistent. If you have one field returning an integer (Book.author_id) and another returning a string (Author.id), then that’s a problem on the part of your schema.

The ID scalar can be used for any number of fields, not just the one field (which may or may not be named id). Similarly, if you want to use Int or String as the type for your id field you can — this will not impact Apollo’s ability to cache your results.

Share
Improve this answer

3

  • what do you mean hidden? Id is top 1 prop for client side components rendering and comparisson.

    – ZiiMakc

    Jan 24, 2020 at 20:52

  • 1

    A book should have an id field, but there's usually no reason for it to expose an author_id field. It should just expose an author field that returns the author object. author_id is an implementation detail — it's relevant to the server because that's how you load the related entity, but it's probably not relevant to the client.

    – Daniel Rearden

    Jan 24, 2020 at 20:57

  • 1

    @RTW rereading your question, I'm realizing you may have been asking about how ID scalars are parsed when they used as inputs like arguments. If that's the case, then keep in mind that if your database driver/query builder/ORM requires an integer as a parameter and you're getting a string argument in the resolver because you used an ID scalar, you can always just call parseInt.

    – Daniel Rearden

    Jan 24, 2020 at 21:00


0

In apollo you can use typePolicies to determintate what field is used as unique identifier. That will resolve a pain of ID! type conversion to string.

const typePolicies = {
  Book: {
    keyFields: ['id'],
  },  
  BookTag: {
    keyFields: ['book_id', 'tag_id'],
  }
}

  return new ApolloClient({
    cache: new InMemoryCache({ typePolicies }),
  })

Share
Improve this answer



Leave a Reply

Your email address will not be published. Required fields are marked *