Created
December 23, 2018 08:04
-
-
Save xwlee/dc83825986c9d46490346b00353366e0 to your computer and use it in GitHub Desktop.
Apollo Server Date Directive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server'); | |
const { GraphQLScalarType, defaultFieldResolver, GraphQLString } = require('graphql'); | |
const { Kind } = require('graphql/language'); | |
const formatDate = require("dateformat"); | |
const typeDefs = gql` | |
directive @date( | |
defaultFormat: String = "mmmm d, yyyy" | |
) on FIELD_DEFINITION | |
scalar Date | |
type Query { | |
today: Date @date | |
} | |
`; | |
const resolvers = { | |
Query: { | |
today: () => { | |
return new Date; | |
} | |
}, | |
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; | |
}, | |
}), | |
}; | |
class FormattableDateDirective extends SchemaDirectiveVisitor { | |
visitFieldDefinition(field) { | |
const { resolve = defaultFieldResolver } = field; | |
const { defaultFormat } = this.args; | |
field.args.push({ | |
name: 'format', | |
type: GraphQLString | |
}); | |
field.resolve = async function ( | |
source, | |
{ format, ...otherArgs }, | |
context, | |
info | |
) { | |
const date = await resolve.call(this, source, otherArgs, context, info); | |
// If a format argument was not provided, default to the optional | |
// defaultFormat argument take by the @date directive | |
return formatDate(date, format || defaultFormat); | |
}; | |
// The formatted Date becomes a String, so the field type must change: | |
field.type = GraphQLString; | |
} | |
} | |
const server = new ApolloServer({ | |
typeDefs, | |
resolvers, | |
schemaDirectives: { | |
date: FormattableDateDirective | |
} | |
}); | |
server.listen().then(({ url }) => { | |
console.log(`Server ready at ${url}`) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment