Should I handle a GraphQL ID as a string on the client?

I am building an application using:

  • MySQL as the backend database
  • Apollo GraphQL server as a query layer for that database
  • Sequelize as the ORM layer between GraphQL and MySQL

As I am building out my GraphQL schema I’m using the GraphQL ID data type to uniquely identify records. Here’s an example schema and its MySQL resolver/connector

Graphql Type:

type Person {
  id: ID!
  firstName: String
  middleName: String
  lastName: String
  createdAt: String
  updatedAt: String
}

Sequelize connector

export const Person = sequelize.define('person', {
  firstName: { type: Sequelize.STRING },
  middleName: { type: Sequelize.STRING },
  lastName: { type: Sequelize.STRING },
});

GraphQL resolver:

Query: {
  person(_, args) {
    return Person.findById(args.id);
}

So that all works. Here’s my question. GraphQL seems to treat the ID type as a string. While the ID value gets stored in the MySQL database as an INT by Sequelize. I can use GraphQL to query the MySQL db with either a string or a integer that matches the ID value in the database. However, GraphQL will always return the ID value as a string.

How should I be handling this value in the client? Should I always convert it to an integer as soon as I get it from GraphQL? Should I modify my sequelize code to store the ID value as a string? Is there a correct way to proceed when using GraphQL IDs like this?

Answer

ID is a scalar type described in the GraphQL specification (working draft October 2016):

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.


Your observation

I can use GraphQL to query the MySQL db with either a string or a integer that matches the ID value in the database. However, GraphQL will always return the ID value as a string.

is aligned with the specification about result coercion:

GraphQL is agnostic to ID format, and serializes to string to ensure consistency across many formats ID could represent

and 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


How should I be handling this value in the client?

  • When working with ID results, treat them as strings.
  • When using ID inputs (in GraphQL variables or input parameters for mutations or queries), you can either use integers or strings.

Should I always convert it to an integer as soon as I get it from GraphQL?

That’s highly depending on your application. There is no general rule that dictates a clear “yes” or “no” here.

Should I modify my sequelize code to store the ID value as a string?

No, that’s not required.

The GraphQL specification about the ID type does not cover how you store the ids, only how a GraphQL server is expected to treat ID input and output. It’s up to the GraphQL layer to ensure this behaviour. How ids are handled in the actual storage is up to the storage layer.

Is there a correct way to proceed when using GraphQL IDs like this?

I hope the above answers also answer this question 🙂