aalises / graphql-global-id

Utility to manage ID fields in GraphQL correctly.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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('XySdXKnaP')).toBe('1234');
});

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.

About

Utility to manage ID fields in GraphQL correctly.

License:MIT License


Languages

Language:JavaScript 100.0%