I'm trying to use class-validator and class-transformer to perform validation on API requests in a Next.js API route.
I've put together this basic API handler to demonstrate:
import { plainToInstance } from 'class-transformer';
import { IsString } from 'class-validator';
import { NextApiRequest, NextApiResponse } from 'next';
class PostBody {
@IsString()
public title!: string;
public content!: string;
}
const validateRequest = (req: NextApiRequest) => {
const request = plainToInstance(PostBody, req.body);
console.log(request);
};
const Handler = (req: NextApiRequest, res: NextApiResponse) => {
validateRequest(req);
res.status(200).json({ message: 'ok' });
};
export default Handler;
If I send a request using postman with body:
{ "title": "Test", "content": "Hello world" }
This is logged to the console:
PostBody { content: 'Hello world' }
If I remove the @IsString()
decorator, this gets logged: PostBody { title: 'Test', content: 'Hello world' }
.
Anyone got any ideas on why the class-validator decorators seem to be removing properties?
Using:
"next": "^12.1.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
The problem might be that your babel is not configured properly.
Try to put this into your babel.config.js
(create the file if you don’t have it already):
module.exports = {
presets: ['next/babel'],
plugins: [['@babel/plugin-proposal-decorators', { 'legacy': true }]],
};
Also don’t forget to put these two devDependencies
into your package.json
:
"@babel/core": "^7.12.9",
"@babel/plugin-proposal-decorators": "^7.17.8",
And for typescript these two lines into your tsconfig.json
"experimentalDecorators": true,
"emitDecoratorMetadata": true,