incetarik / nestjs-graphql-zod

A library providing dynamic GraphQL object classes from their zod validation objects.
Mozilla Public License 2.0
79 stars 11 forks source link

Caching issue with MutationWithZod #22

Open binhnc1991 opened 10 months ago

binhnc1991 commented 10 months ago

Environment:

zod: 3.21.4
nestjs-graphql-zod: 3.2.0

Description: I have encountered a caching issue when utilizing the MutationWithZod decorator from "nestjs-graphql-zod" library. Despite having server caching disabled in my project, there seems to be an issue with caching. Here's a brief overview of the scenario:

const testSchema = z
  .object({
    fieldA: z.boolean(),
    fieldB: z.string().optional(),
  });

@MutationWithZod(testSchema)
async testMutation() {
  const result = await testFunction();

  return result;
}

Upon the first invocation of the GraphQL mutation, the fieldB value is correctly included in the GraphQL response. However, in subsequent calls, if the returned result from testFunction lacks fieldB (e.g., only{ fieldA: true }is returned), the previous value of fieldB is unexpectedly preserved. That means, the value of an optional field persists even when not included in the latest response.

Expected Behavior: It should not retain the value of any optional field if it is not present in the subsequent GraphQL mutation responses.

FYI, a workaround that uses modelFromZod

const testSchemaModel = modelFromZod(testSchema);

@Mutation(() => testSchema)
async testMutation() {
  const result = await testFunction();

  return result;
}

Using this workaround eliminates the caching problem, and the behavior aligns with the expected outcome. Thank you

incetarik commented 10 months ago

Hello @binhnc1991 ! Thank you for this issue, I'll check this out when I'm free. This is very interesting indeed, as I don't remember any caching included in the decorators such as MutationWithZod. I'll still check that out and will do the changes accordingly if needed.

When I see the underlying issue and fix it if there was a problem, I'll notify you here about the fix. Have a nice day.

wyat-soule-waggoner commented 2 months ago

Hello, I am getting this issue now too. Just want to keep it on your radar - i might look into the code soon as well as it is a big issue for us.

happens on my @Query with the input.

here is what i have

  @Query(() => [DateMetricData])
  async getMetrics(
    @CurrentUser() id: string,
    @Args('input') input: GetMetricDataInput
  ): Promise<DateMetricData[]> {
    input.userId = id;
    return await this._numberKeeperService.getMetrics(input);
  }
@InputType()
export abstract class GetMetricDataInput extends inputFromZod(
  GetMetricDataSchema
) {
  constructor() {
    super();
  }
}
export const GetMetricDataSchema = z.object({
  all: z.boolean().optional(),
  date: z.string().optional(),
  // dateEnd: z.string().optional(),
  // dateStart: z.string().optional(),
  id: z.string().optional(),
  metricTime: z.enum([
    MetricTime.quarter,
    MetricTime.day,
    MetricTime.week,
    MetricTime.all
  ]),
  metricType: z.enum([
    MetricType.all,
    MetricType.rock,
    MetricType.brick,
    MetricType.dailyNumber
  ]),
  userId: z.string().optional()
});

if i should be doing this another way, please let me know.