🐛

[NestJS] bodyで受け取ったbooleanの値が正しくパースされない問題と解決策

2024/06/27に公開

事象

NestJSでmultipart/form-dataでリクエストを受け取った際に、booleanの値が正しくパースされない問題があります。
具体的には、falseの値がtrueとしてパースされてしまいます。(というかtrueにしかなりません)

該当する環境

  • ValidationPipeを使用しており、enableImplicitConversion: trueになっている
  • class-transformerを使用している(執筆時の最新バージョンは0.5.1)

結論

class-transformerが原因です。
multipart/form-dataではパラメータをstringとして受け取るのですが、string->booleanの変換に対応していません。

現時点(6/27)PRが出ていますがマージされておらず。

解決策

class-transformerは2021年頃からメンテナンスが停止しているようです。
https://github.com/typestack/class-validator/issues/1775

なので今回はclass-transformerをforkして修正を行いました。
https://www.npmjs.com/package/@takecchi/class-transformer

使用方法

  1. (任意) class-transformerをアンインストール

インストールしたままでも良いですが、 機能的にはclass-transformerと同じなので自分はアンインストールしました。
インポート先をclass-transformerから@takecchi/class-transformerに変更するだけです。

npm uninstall class-transformer
  1. @takecchi/class-transformerをインストール
npm install @takecchi/class-transformer
  1. transformerPackage@takecchi/class-transformerを指定する
  app.useGlobalPipes(
    new ValidationPipe({
        transformerPackage: require('@takecchi/class-transformer'),
        transform: true,
        transformOptions: { enableImplicitConversion: true },
    }),
  );

まとめ

この結論に至るまでに再現リポジトリを作ったり、NestJSのソースコードを読んだりしたので、
本当はその話も書こうと思っていたのですが、結論書いたら不要な気がしたので割愛しました。

気になる人向けに再現リポジトリだけ置いておきます。
https://github.com/takecchi/nestjs-boolean-problem

GitHubで編集を提案

Discussion