With GraphQL, we can create scalar types as we do with create object types and other compound data types.
In this article, we’ll look at how to create scalar types with Express-GraphQL.
GraphQLScalarType
We can create a GraphQL scalar type with the GraphQLScalarType
constructor. To create a scalar type, we have to give it a name, an optional description, and ways to serialize and parse the values.
The constructor takes an object with the following fields:
name
— the name of the scalar type we want to define as a stringdescription
— an optional string with the description of our typeserialize
— a function that takes in avalue
parameter, which can be anything and then return something that we want to transform it to for transmissionparseValue
— an optional function that takes avalue
parameter, which can be anything and then return the parsed value as we wish toparseLiteral
— a function that takes an abstract syntax tree object, which is the value of the literal, then we return something that we want to transform the value to.
Example
For example, we can write the following to create a scalar type and return it in the response:
const express = require('express');
const graphqlHTTP = require('express-graphql');
const graphql = require('graphql');
const dateValue = (value) => {
if (value instanceof Date) {
return +value;
}
}
const DateType = new graphql.GraphQLScalarType({
name: 'Date',
serialize: dateValue,
parseValue: dateValue,
parseLiteral(ast) {
return dateValue(ast.value);
}
});
const queryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: {
currentDate: {
type: DateType,
resolve: () => {
return new Date();
}
}
}
});
const schema = new graphql.GraphQLSchema({ query: queryType });
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: true,
}));
app.listen(3000, () => console.log('server started'));
In the code above, we defined the dateValue
function as follows:
const dateValue = (value) => {
if (value instanceof Date) {
return +value;
}
}
In the function, we check if the value
is created from the Date
constructor, if it is, then we return the Date
object converted to a timestamp.
Then we use it to create a new scalar type called Date
as follows:
const DateType = new graphql.GraphQLScalarType({
name: 'Date',
serialize: dateValue,
parseValue: dateValue,
parseLiteral(ast) {
return dateValue(ast.value);
}
});
We passed in the name, which is 'Date'
. Then we have the serialize
property with the dateValue
to return the timestamp as the serialized version of the scalar type.
Likewise, we parse the Date
object into a UNIX timestamp with the same function.
In the parseLiteral
function, we pass in the value to the dateValue
function to convert the Date
object into a UNIX timestamp.
Then we create our query type so that we can return the timestamp response to the user as follows:
const queryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: {
currentDate: {
type: DateType,
resolve: () => {
return new Date();
}
}
}
});
We create the Query
object type so that we can query it and then in the fields
property, we return a currentDate
field that’s of the Date
scalar type that we defined earlier.
In the resolve
method, we just return new Date()
, which will automatically parsed into a UNIX timestamp in the response since that’s how we decided to serialize it in the dateValue
function.
Then when we make a query as follows:
{
currentDate
}
we get something like:
{
"data": {
"currentDate": 1579464244268
}
}
where the currentDate
is replaced with the current UNIX timestamp.
Conclusion
We can create a scalar type by using the GraphQLScalarType
constructor.
To define one, we have to pass in functions to serialize and parse values as we wish to.