Skip to content
Utility to manage ID fields in GraphQL correctly.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.npmignore
LICENSE
README.md
package.json

README.md

Simple utility to manage our ID fields in GraphQL correctly.

Do you like our open source? We are looking for skilled JavaScript developers to help us build it. Check our open positions: https://jobs.kiwi.com/

Install

yarn add @kiwicom/graphql-global-id

Basic usage

This utility automatically creates correct opaque and globally unique ID type so you don't have to think about it.

import GlobalID from '@kiwicom/graphql-global-id';

export default new GraphQLObjectType({
  name: 'TypeName',
  fields: {
    id: GlobalID(({ id }) => id),
  },
});

The example above would create this type:

type TypeName {
  """
  The globally unique ID of an object. You can unmask this ID to get original
  value but please note that this unmasked ID is not globally unique anymore and
  therefore it cannot be used as a cache key.
  """
  id(opaque: Boolean = true): ID!
}

You can easily access original ID (also known as "database ID" or "original ID") using opaque parameter. This is very handy for legacy applications. However, try to always prefer the opaque version.

Sometimes it's necessary to use the non-opaque version. And you may want to expose different ID than originally used for the opaque and unique ID. You can do so using the second optional argument:

// This is internal ID fetcher to ensure unique ID values across the whole GraphQL universe:
const idFetcher = ({ id, name, email }) => `${id}:${name}:${email}`;

// This fetcher exposes just the ID because non-opaque IDs are not unique anyway:
const opaqueIdFetcher = ({ id }) => id;

const fields = {
  id: GlobalID(idFetcher, opaqueIdFetcher),
};

Restoring original ID

GlobalID used in previous examples accepts readable (unmasked ID) and returns opaque ID. You can revert this process in case you need to access the original unmasked ID. Check the following test to get the idea:

import { fromGlobalId } from '@kiwicom/graphql-global-id';

it('returns correct original ID', () => {
  expect(fromGlobalId('TG9jYXRpb246bG9uZG9uX2di')).toBe('london_gb');
});

You should always use this function because the way how this utility works with masking and unmasking is just an internal detail.

Tips

It is possible to fetch both ID versions at the same time in GraphQL:

{
  customerBookings {
    id # or id(opaque: true)
    bookingID: id(opaque: false)
  }
}

This is handy especially when you are migrating old code to this new type. Just change something like deprecated databaseID to databaseID: id(opaque: false) and that's it.

You can’t perform that action at this time.