Scalars¶
A GraphQL object type has a name and fields, but at some point those fields have to resolve to some concrete data. That's where the scalar types come in: they represent the leaves of the query (read more here). GraphQL includes the following default types: Int
, Float
, String
, Boolean
and ID
. In addition to these built-in types, you may need to support custom atomic data types (e.g., Date
).
Code first¶
The code-first approach ships with five scalars in which three of them are simple aliases for the existing GraphQL types.
ID
(alias forGraphQLID
) - represents a unique identifier, often used to refetch an object or as the key for a cacheInt
(alias forGraphQLInt
) - a signed 32‐bit integerFloat
(alias forGraphQLFloat
) - a signed double-precision floating-point valueGraphQLISODateTime
- a date-time string at UTC (used by default to representDate
type)GraphQLTimestamp
- a signed integer which represents date and time as number of milliseconds from start of UNIX epoch
The GraphQLISODateTime
(e.g. 2019-12-03T09:54:33Z
) is used by default to represent the Date
type. To use the GraphQLTimestamp
instead, set the dateScalarMode
of the buildSchemaOptions
object to 'timestamp'
as follows:
Likewise, the GraphQLFloat
is used by default to represent the number
type. To use the GraphQLInt
instead, set the numberScalarMode
of the buildSchemaOptions
object to 'integer'
as follows:
In addition, you can create custom scalars. For example, to create a Date
scalar, simply create a new class.
With this in place, register DateScalar
as a provider.
Now we can use the Date
type in our classes.
Schema first¶
To define a custom scalar (read more about scalars here), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the graphql-type-json
package for demonstration purposes. This npm package defines a JSON
GraphQL scalar type.
Start by installing the package:
Once the package is installed, we pass a custom resolver to the forRoot()
method:
Now we can use the JSON
scalar in our type definitions:
Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the Date
type.
With this in place, register DateScalar
as a provider.
Now we can use the Date
scalar in type definitions.
By default, the generated TypeScript definition for all scalars is any
- which isn't particularly typesafe.
But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:
Hint
Alternatively, you can use a type reference instead, for example: DateTime: Date
. In this case, GraphQLDefinitionsFactory
will extract the name property of the specified type (Date.name
) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.
Now, given the following GraphQL custom scalar types:
We will now see the following generated TypeScript definitions in src/graphql.ts
:
Here, we've used the customScalarTypeMapping
property to supply a map of the types we wish to declare for our custom scalars. We've
also provided an additionalHeader
property so that we can add any imports required for these type definitions. Lastly, we've added
a defaultScalarType
of 'unknown'
, so that any custom scalars not specified in customScalarTypeMapping
will be aliased to
unknown
instead of any
(which TypeScript recommends using since 3.0 for added type safety).
Hint
Note that we've imported _BigNumber
from bignumber.js
; this is to avoid circular type references.