You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS+PostgreSQL存储JSONB遇「必须为JSON字符串」错误排查

NestJS中使用JSONB字段时遇到"content must be a json string"错误的解决方法

问题根源

错误来自DTO中的@IsJSON()装饰器——这个装饰器的作用是验证输入是否为合法的JSON字符串(比如"{\"messages\": [...], \"detail\": \"xxx\"}"格式),但你在Postman中提交的是嵌套JSON对象,并非字符串,因此验证不通过。

解决方案

因为content是结构化嵌套对象,需要使用class-validator的嵌套验证机制,步骤如下:

  1. 将IContent接口转换为类
    TypeScript接口仅在编译时存在,class-validator无法借助接口进行运行时验证,因此需要把接口改成带验证装饰器的类:
import { IsArray, IsString } from 'class-validator';

export class Content {
  @IsArray()
  @IsString({ each: true }) // 确保messages数组的每个元素都是字符串
  messages: string[];

  @IsString()
  detail: string;
}
  1. 修改CreateUpdateDTO的验证规则
    使用@ValidateNested()和@Type()替换原有的@IsJSON(),实现嵌套对象的验证:
import { ValidateNested, Type } from 'class-validator';
import { Content } from './path-to-content-class'; // 替换为你的Content类实际路径

export class CreateUpdateDTO {
  @ValidateNested()
  @Type(() => Content)
  content: Content;
}
  1. 保持实体类配置不变
    你的实体类中@Column('jsonb', { nullable: false, default: {} })的配置是正确的,TypeORM会自动将嵌套对象映射到PostgreSQL的JSONB字段。

验证效果

修改完成后,你在Postman中提交的原始JSON请求体:

{
  "content": {
     "messages": ["testing", "testing", "123"],
     "detail": "some detail"
  }
}

就能正常通过验证并写入数据库的JSONB字段中。

内容的提问来源于stack exchange,提问作者Dora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 02:10:02