Categories
GraphQL

Creating GraphQL Scalar Types with Express-GraphQL

Spread the love

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 string
  • description — an optional string with the description of our type
  • serialize — a function that takes in a value parameter, which can be anything and then return something that we want to transform it to for transmission
  • parseValue — an optional function that takes a value parameter, which can be anything and then return the parsed value as we wish to
  • parseLiteral — 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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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