60

Is it possible to have a define a field as Date or JSON in my graphql schema ?

type Individual {
    id: Int
    name: String
    birthDate: Date
    token: JSON
}

actually the server is returning me an error saying :

Type "Date" not found in document.
at ASTDefinitionBuilder._resolveType (****node_modules\graphql\utilities\buildASTSchema.js:134:11)

And same error for JSON...

Any idea ?

Mohamed Taboubi
  • 6,663
  • 11
  • 55
  • 87
  • While the solutions given in this thread is appetizing and complete. I have seen that when you are using adapters like https://github.com/Soluto/graphql-to-mongodb - then we cannot create our own types - so in that situation I directly store dates as time in millis within DB and utilize float type. js had (new Date()).getTime() to assist and use resolver to have it convert to required date format as string wherever needed - new Date(1324339200000); date.toString("MMM dd"); – Karan Bhandari May 15 '21 at 05:52

2 Answers2

80

Have a look at custom scalars: https://www.apollographql.com/docs/graphql-tools/scalars.html

create a new scalar in your schema:

scalar Date
    
type MyType {
    created: Date
}

and create a new resolver:

import { GraphQLScalarType } from 'graphql';
import { Kind } from 'graphql/language';

const resolverMap = {
    Date: new GraphQLScalarType({
        name: 'Date',
        description: 'Date custom scalar type',
        parseValue(value) {
            return new Date(value); // value from the client
        },
        serialize(value) {
            return value.getTime(); // value sent to the client
        },
        parseLiteral(ast) {
            if (ast.kind === Kind.INT) {
            return parseInt(ast.value, 10); // ast value is always in string format
            }
            return null;
        },
    })
};
goliatone
  • 2,183
  • 16
  • 29
Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
  • how is the query in that example?. 10.02.1993?? – ValRob Mar 17 '20 at 09:16
  • Just wanted to mentioned that this snippet only works when the date you pass is a number. "2020-01-01" for example, although a valid date, won't be parsed as it only does so expecting a number. – sebastianf182 Oct 16 '20 at 22:14
19

Primitive scalar types in GraphQL are Int, Float, String, Boolean and ID. For JSON and Date you need to define your own custom scalar types, the documentation is pretty clear on how to do this.

In your schema you have to add:

scalar Date

type MyType {
   created: Date
}

Then, in your code you have to add the type implementation:

import { GraphQLScalarType } from 'graphql';

const dateScalar = new GraphQLScalarType({
  name: 'Date',
  parseValue(value) {
    return new Date(value);
  },
  serialize(value) {
    return value.toISOString();
  },
})

Finally, you have to include this custom scalar type in your resolvers:

const server = new ApolloServer({
  typeDefs,
  resolvers: {
    Date: dateScalar,
    // Remaining resolvers..
  },
});

This Date implementation will parse any string accepted by the Date constructor, and will return the date as a string in ISO format.

For JSON you might use graphql-type-json and import it as shown here.

iamkirill
  • 310
  • 1
  • 6
  • 12
Martín De la Fuente
  • 6,155
  • 4
  • 27
  • 28