Search code examples
next.jsclass-validatorclass-transformer

Why are class-validator decorators removing properties when used with class-transformer


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",

Solution

  • 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,