Date and Json in type definition for graphql

Date and Json in type definition for graphql


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_modulesgraphqlutilitiesbuildASTSchema.js:134:11)

And same error for JSON…

Any idea ?

1

  • While the solutions given in this thread is appetizing and complete. I have seen that when you are using adapters like 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, 2021 at 5:52

3 Answers
3


81

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;
        },
    })
};

2

  • how is the query in that example?. 10.02.1993??

    – ValRob

    Mar 17, 2020 at 9: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, 2020 at 22:14


22

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.


0

I think that the easiest way today is to use the popular graphql-scalars npm package. You can follow the quick-start documentation on the guild for the package.

Basically, after installing the package, you can add to your graphql schema (your "typeDefs") the following line:

scalar DateTime

Then, just add one line into your resolvers (plus of course you need the import statement):

import { DateTimeResolver} from 'graphql-scalars'

export const resolvers = {
    DateTime: DateTimeResolver,

    Query: {
     ...
    },
    ...
};

After that, you can just use DateTime as any other scalar, e.g.

type Post {
    id: ID!
    title: String!
    content: String!
    createdAt: DateTime!
    updatedAt: DateTime!
}

Note that this is exactly the DateTime type used in Prisma.



Leave a Reply

Your email address will not be published. Required fields are marked *