graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Extend `dateScalarMode` and `numberScalarMode` to allow custom scalars to be used by default

Open pting-me opened this issue 10 months ago • 0 comments

Is there an existing issue that is already proposing this?

  • [X] I have searched the existing issues

Is your feature request related to a problem? Please describe it

I was trying to override the DateTime scalar with another scalar from graphql-scalars.

GraphQLModule.forRoot<ApolloDriverConfig>({
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  driver: ApolloDriver,
  resolvers: {
    DateTime: GraphQLDateTime,
  },
}),

This works fine when defining the field explicitly with the new scalar, but only if EVERY Date field has been updated.

@Field(() => GraphQLDateTime)
createdAt: Date;

// This will be automatically added as GraphQLISODateTime
// which causes a naming conflict
@Field()
updatedAt: Date;

Describe the solution you'd like

Ideally BuildSchemaOptions would be modified to look something like this:

/** Proposal 1 - Scalar names */
interface BuildSchemaOptions1 {
  /** @default 'DateTime' */
  dateScalarMode?: string | DateScalarMode;
  /** @default 'Float' */
  numberScalarMode?: string | NumberScalarMode;
  /* ... */
}

Alternatively, we can also pass in GraphQL scalar types:

/** Proposal 2 - Scalar objects */
interface BuildSchemaOptions2 {
  /** @default GraphQLISODateTime */
  dateScalarMode?: GraphQLScalarType<Date, unknown> | DateScalarMode;
  /** @default GraphQLFloat */
  numberScalarMode?: GraphQLScalarType<Date, unknown> | NumberScalarMode;
  /* ... */
}

This second approach requires the user to repeat the overrides in resolvers and buildSchemaOptions, and can still be difficult to understand what to do when there's a naming conflict.

Teachability, documentation, adoption, migration strategy

A simple map of the existing options to the new options should suffice for backwards compatibility.

What is the motivation / use case for changing the behavior?

The errors kept citing a naming conflict but it was really confusing when I had removed any instances of the default GraphQLISODateTime. I would have expected the configuration above to override the DateTime scalar.

After understanding the problem, I had to change every @Field() to explicitly return the proper type. That can be very problematic in large code bases.

pting-me avatar Apr 17 '24 15:04 pting-me