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
3 Answers
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??
– ValRobMar 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.
– sebastianf182Oct 16, 2020 at 22:14
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.
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.
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");
May 15, 2021 at 5:52