Disclaimer: These are just my personal notes to help me articulate concepts I’m learning. They’re not meant to be used as a tutorial.
Why use a custom date scalar type in GraphQL?
Well first, what is a scalar?
A scalar is a type. GraphQL has four default scalar types:
Int
Float
String
Boolean
Notice there is no Date
type.
By default, GraphQL uses seconds internally. This means that even if your database stores a createdAt
date in a readable format like 019-06-12 09:49:55.058+06:30
, GraphQL will still convert it to a long seconds string like 1560310894541
before returning it to the client, which isn’t very readable.
Also, think about the semantics of this. Imagine you have a schema for a Post
type where one of the fields is createdAt
. For example:
type Post { id: ID! text: String! createdAt: # what do we return here? user: User! comments: [Comment!]! }
What should we return for the createdAt
field? There is no Date
format. So the best we can do is return a string. But this means that the client will receive a non-human readable string of seconds for the createdAt
field.
Luckily GraphQL lets us add our own custom scalar types.
We can use a package called graphql-iso-date.
1. Add a Date
scalar in your root schema
const linkSchema = gql` scalar Date type Query { ... } type Mutation { ... } type Subscription { ... } `;
2. Add a resolver at the highest level of the resolver map that tells the program to return a GraphQLDateTime
for the type Date
. In my case, I’m doing something like this:
import { GraphQLDateTime } from "graphql-iso-date"; const customScalarResolver = { Date: GraphQLDateTime }; export default [ customScalarResolver, userResolvers, postResolvers, commentResolvers ];
3. Then, in your schema, you can return an actual Date
scalar type for the createdAt
field on the Post
type Post { id: ID! text: String! createdAt: Date! user: User! comments: [Comment!]! }
Now, when we run the post
query, we get back a more readable date format:
{ "data": { "post": { "id": "1", "text": "My first post.", "createdAt": "2019-06-12T03:29:56.901Z" } } }