GraphQL.js - timestamp scalar type?

U-ways picture U-ways · Aug 13, 2018 · Viewed 11.3k times · Source

I am building a GraphQL schema programmatically and in need of a Timestamp scalar type; a Unix Epoch timestamp scalar type:

const TimelineType = new GraphQLObjectType({
  name: 'TimelineType',
  fields: () => ({
    date:  { type: new GraphQLNonNull(GraphQLTimestamp)  },
    price: { type: new GraphQLNonNull(GraphQLFloat)      },
    sold:  { type: new GraphQLNonNull(GraphQLInt)        }
  })
});

Unfortunately, GraphQL.js doesn't have a GraphQLTimestamp nor a GraphQLDate type so the above doesn't work.

I am expecting a Date input and I want to convert that to a timestamp. How would I go about creating my own GraphQL timestamp type?

Answer

U-ways picture U-ways · Aug 13, 2018

There is an NPM package with a set of RFC 3339 compliant date/time GraphQL scalar types; graphql-iso-date.


But for starters, You should use GraphQLScalarType to build your own scalar type in GraphQL programmatically:

/** Kind is an enum that describes the different kinds of AST nodes. */
import { Kind } from 'graphql/language';
import { GraphQLScalarType } from 'graphql';

const TimestampType = new GraphQLScalarType({
  name: 'Timestamp',
  serialize(date) {
    return (date instanceof Date) ? date.getTime() : null
  },
  parseValue(date) {
    try           { return new Date(value); }
    catch (error) { return null; }
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.INT) {
      return new Date(parseInt(ast.value, 10));
    }
    else if (ast.kind === Kind.STRING) {
      return this.parseValue(ast.value);
    }
    else {
      return null;
    }
  },
});

But instead of re-inventing the wheel, this issue (#550) was already discussed and Pavel Lang came up with a decent GraphQLTimestamp.js solution (my TimestampType is derived from his).