Scalars

The GraphQL includes the following default types: Int, Float, String, Boolean and ID. However, sometimes you may need to support custom atomic data types (e.g. Date).

Schema first

In order to define a custom scalar (read more about scalars here), we have to create a type definition and a dedicated resolver as well. Here (as in the official documentation), we’ll take the graphql-type-json package for demonstration purposes. This npm package defines a JSON GraphQL scalar type. Firstly, let’s install the package:

  1. $ npm i --save graphql-type-json

Once the package is installed, we have to pass a custom resolver to the forRoot() method:

  1. import * as GraphQLJSON from 'graphql-type-json';
  2. @Module({
  3. imports: [
  4. GraphQLModule.forRoot({
  5. typePaths: ['./**/*.graphql'],
  6. resolvers: { JSON: GraphQLJSON },
  7. }),
  8. ],
  9. })
  10. export class ApplicationModule {}

Now we can use JSON scalar in our type definitions:

  1. scalar JSON
  2. type Foo {
  3. field: JSON
  4. }

Another form of defining the scalar type is to create a simple class. Let’s say that we would like to enhance our schema with the Date type.

  1. import { Scalar, CustomScalar } from '@nestjs/graphql';
  2. import { Kind, ValueNode } from 'graphql';
  3. @Scalar('Date')
  4. export class DateScalar implements CustomScalar<number, Date> {
  5. description = 'Date custom scalar type';
  6. parseValue(value: number): Date {
  7. return new Date(value); // value from the client
  8. }
  9. serialize(value: Date): number {
  10. return value.getTime(); // value sent to the client
  11. }
  12. parseLiteral(ast: ValueNode): Date {
  13. if (ast.kind === Kind.INT) {
  14. return new Date(ast.value);
  15. }
  16. return null;
  17. }
  18. }

Afterward, we need to register DateScalar as a provider.

  1. @Module({
  2. providers: [DateScalar],
  3. })
  4. export class CommonModule {}

And now we are able to use Date scalar in our type definitions.

  1. scalar Date

Code first

In order to create a Date scalar, simply create a new class.

  1. import { Scalar, CustomScalar } from '@nestjs/graphql';
  2. import { Kind, ValueNode } from 'graphql';
  3. @Scalar('Date', type => Date)
  4. export class DateScalar implements CustomScalar<number, Date> {
  5. description = 'Date custom scalar type';
  6. parseValue(value: number): Date {
  7. return new Date(value); // value from the client
  8. }
  9. serialize(value: Date): number {
  10. return value.getTime(); // value sent to the client
  11. }
  12. parseLiteral(ast: ValueNode): Date {
  13. if (ast.kind === Kind.INT) {
  14. return new Date(ast.value);
  15. }
  16. return null;
  17. }
  18. }

Once it’s ready, register DateScalar as a provider.

  1. @Module({
  2. providers: [DateScalar],
  3. })
  4. export class CommonModule {}

Now you can use Date type in your classes.

  1. @Field()
  2. creationDate: Date;