instantcommerce / next-api-decorators

Collection of decorators to create typed Next.js API routes, with easy request validation and transformation.
https://next-api-decorators.vercel.app
MIT License
415 stars 29 forks source link

Body validation/transform does not work #444

Closed mathcrln closed 2 years ago

mathcrln commented 2 years ago

Describe the bug A clear and concise description of what the bug is.

Neither the validation of the body nor the transformation with class-transformer seem to work. I have both class-transformer and class-validator installed. Yet, when I make a POST request to the concerned API Route with a body, it is not transformed into the appropriate object from the DTO. Furthermore, no validation is done either. The following code go straight to my prisma upsert method call which, of course reject the entry (even if it's correct) because it has not been parsed.

I am aware that existing issues has been opened in the past related to this same apparent bug: #402, 357. Nevertheless, none of the suggestions offered in these issues seemed to solve my problem.

class CreateProgramDto {
    @IsString()
    @IsNotEmpty()
    name!: string;

    @IsString()
    @IsNotEmpty()
    slug!: string;

    @IsString()
    @IsNotEmpty()
    description!: string;

    @IsString()
    image!: string;

    @IsNumber({}, { each: true })
    hosts!: number[];
}
    @Post()
    async createProgram(@Body(ValidationPipe) body: CreateProgramDto) {
        const program = await prisma.program.upsert({
            where: { slug: body.slug },
            create: {
                name: body.name,
                slug: body.slug,
                description: body.description,
                image: body.image,
                hosts: {
                    connect: body.hosts.map((id: number) => ({ id })),
                },
            },
            update: {},
        });
        return program;
    }

To Reproduce Steps to reproduce the behavior:

  1. Create a brand new Nest.js (^12.1.6) project with SWC
  2. Create an API route with next-api decorators
  3. Create the appropriate DTO and install class-transformer and class-validator
  4. Attempt to POST data to the endpoint from Insomnia
  5. Observe that the body hasn't been parsed

Expected behavior A clear and concise description of what you expected to happen.

I expect for the body to have been parsed following the DTO and for an error to have been thrown before the code reach the Prisma call if the body validation was incorrect.

Additional context Add any other context about the problem here. Here is my tsconfig.json. Don't hesitate if you need any more information.

{
    "compilerOptions": {
        "target": "es2015",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noEmit": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "jsx": "preserve",
        "baseUrl": ".",
        "incremental": true
    },
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
    "exclude": ["node_modules"]
}
mathcrln commented 2 years ago

After many hours debugging and reading all sorts of documentations as to why this would happen, I realize about the silly mistake I made: I was testing my API Routes with Insomnia/Postman and forgot to set the "ContentType: application/json" header in the request. Once I did that, everything started working properly.

But if I may ask, shouldn't the validator have caught that anyway? While I do realize that it's unlikely that anyone will target my API routes in this way (especially as they will be protected), in the end it still triggered a database call with the invalid body. Shouldn't the ValidationPipe trigger an error if it can't serialize the body properly?

github-actions[bot] commented 2 years ago

:tada: This issue has been resolved in version 1.8.0-beta.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

ggurkal commented 2 years ago

Hi @mathcrln

Thanks for the report. The fix has been released in the beta channel. Let me know if it fix your issue as well.

github-actions[bot] commented 2 years ago

:tada: This issue has been resolved in version 1.8.2 :tada:

The release is available on:

Your semantic-release bot :package::rocket: