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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:07:38