Creating a Custom Scalar with Nexus. GraphQL

I’m using Nexus and TypeScript as a code first approach for a GraphQL server at work. Today I needed to have one of the fields be a DateTime Scalar type to match with an AWS-SDK library I’m creating an GraphQL API for.

I found an example in the documentation on Nexus, but it wasn’t fully explained. So I thought I would write this post to help others that are creating custom GraphQL Scalars with Nexus.

Below is the example given in the Nexus documentation, which I’ve slightly changed to match how I had to use it in my case.

So let me just explain what it does and then I will show how to use it.

const DateScalar = scalarType({
  name: "dateTime",
  asNexusMethod: "dateTime",
  description: "Date custom scalar type",
  parseValue(value) {
    const date = new Date(value);
    return date.getTime();
  },
  serialize(value) {
    return new Date(value);
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  },
});

For my use case the AWS API was returning the date and time in milliseconds, such as 1239809804. So the first function I will cover is the one that handles data coming from the backend.

When you do a query and pull data from the backend the serialize() function is applied and will transform the data as you specify. In this case I want to send a Date to the front end.

The parseValue() function is used in input from the front end. So if you call a query with:

getData(Where: { DateTime: "someDateTime" }){}

Then the function, in my use case will execute the parseValue() function and turn it into milliseconds.

Once you have created your scalar you will need to add it into the makeSchema() function of Nexus to make it appear in the auto-generated schema.

Then it will need to be added to types and input objects. As shown below:

const sampleType = objectType({
    name: "sampleType",
    definition(t) {
        t.id("id");
        t.string("someData");
        t.field("timestamp",{ type: "dateTime"})
    }
});

const sampleInput = inputObjectType({
    name: "sampleInput",
    definition(t) {
        t.string("sampleData", { required: true});
        t.field("startTime", { type: "dateTime" })
    }
});

I have yet to use parseLiteral(), so I’m not sure when that’s applied. If someone wants to further explain that part please do inform me.

Please let me know if you have any questions. I would also like to know what difficulties you may be having with GraphQL to address in future blog posts.

Posted in

Andrew Obrigewitsch

Andrew is a Senior Software Engineer based out of Sacramento California, he works at are large software company that handles massive data sets. He builds both backend and frontend solutions to handle said large data sets. He is passionate about new technologies which make developing faster, easier and achieve more uniform and predication results.

Reader Interactions

Comments

Leave a Reply

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