NextJS API Handler返回Decimal自动转字符串问题解决问询
问题:NextJS API接口中Prisma返回的Decimal类型被转为字符串返回
NextJS的API处理器会自动将Decimal类型转为字符串,以下是复现代码:
import { PrismaClient } from "@prisma/client"; const handler = async (req, res) => { const prisma = new PrismaClient(); const result = await prisma.Test.findMany({}); console.log(result); res.status(200).json(result); // res.status(200).json({ name: "John Doe", age: 34, salary: 12345.75 }); }; export default handler;
现象:
- 接口返回结果中,
salary被转为字符串:
[{"id":"dafsdfd","name":"John Doe","age":35,"salary":"1234.56","updatedAt":"2023-11-21T08:45:55.000Z"}]
- 控制台打印的结果中
salary是正确的数字类型:
[
{
id: 'dafsdfd',
name: 'John Doe',
age: 35,
salary: 1234.56,
updatedAt: 2023-11-21T08:45:55.000Z
}
]
- 手动构造包含数字的对象返回时,Decimal类型能正确返回:
res.status(200).json({ name: "John Doe", age: 34, salary: 12345.75 });
解决方案
方法1:查询后手动转换Decimal字段为数字
遍历查询结果,将Decimal类型的字段转为Number类型:
import { PrismaClient } from "@prisma/client"; const handler = async (req, res) => { const prisma = new PrismaClient(); const result = await prisma.Test.findMany({}); // 转换Decimal字段为数字 const transformedResult = result.map(item => ({ ...item, salary: Number(item.salary) })); res.status(200).json(transformedResult); }; export default handler;
方法2:在Prisma查询中直接转换
使用Prisma的select配合数据库的类型转换函数(以PostgreSQL的CAST为例),在查询阶段就将Decimal转为数字:
import { PrismaClient } from "@prisma/client"; import { Prisma } from '@prisma/client'; const handler = async (req, res) => { const prisma = new PrismaClient(); const result = await prisma.Test.findMany({ select: { id: true, name: true, age: true, salary: Prisma.sql`CAST("salary" AS DOUBLE PRECISION)`, updatedAt: true } }); res.status(200).json(result); }; export default handler;
方法3:自定义JSON序列化逻辑
利用JSON.stringify的replacer参数统一处理Decimal类型:
import { PrismaClient } from "@prisma/client"; import { Decimal } from '@prisma/client/runtime/library'; const handler = async (req, res) => { const prisma = new PrismaClient(); const result = await prisma.Test.findMany({}); // 自定义序列化规则,将Decimal转为数字 const jsonString = JSON.stringify(result, (key, value) => { if (value instanceof Decimal) { return Number(value); } return value; }); res.setHeader('Content-Type', 'application/json'); res.status(200).send(jsonString); }; export default handler;
方法4:全局配置Prisma Client的Decimal处理
在初始化Prisma Client时,通过transformers配置全局转换规则(需Prisma 4.16+版本):
import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient({ transformers: [ { result: { Decimal: (value) => Number(value) } } ] }); const handler = async (req, res) => { const result = await prisma.Test.findMany({}); res.status(200).json(result); }; export default handler;
内容的提问来源于stack exchange,提问作者Bipin Vellathingal
相关产品推荐
相关产品推荐

