Next.js调用gRPC传递字符串数组时后端接收为null如何解决
问题原因
核心问题是你直接把JSON.parse(_req.body)得到的普通JavaScript对象传给了gRPC客户端方法,没有走proto定义的消息序列化逻辑。
- gRPC Node客户端对传入的普通对象不会做严格的proto字段匹配校验,
repeated修饰的数组字段在这种传参模式下很容易丢失映射,你这里的object_uuid就是这种情况,只有标量类型的size因为结构简单被识别到了,所以能正常赋值。 - 终端直接请求能正常工作,是因为终端请求打到服务端后,走的是服务端内置的JSON转proto逻辑,服务端的转码是严格对齐proto定义的,不会丢字段。
- 你写的JSON请求体没有语法错误,字段名、结构完全符合要求。
修复方法
不要直接传普通JS对象给gRPC方法,用proto编译生成的请求消息类构造正式的请求参数再传入:
- 引入proto编译生成的
LogRequest消息类 - 实例化消息对象,按生成类提供的setter方法给字段赋值
- 把实例化好的消息对象传给gRPC调用方法
修复后的Next.js API层参考代码:
// 替换成你项目里proto生成代码的实际引入路径 import { LogRequest } from '@/generated/log_pb'; export default (_req: NextApiRequest, res: NextApiResponse) => { const reqBody = JSON.parse(_req.body); // 构造符合gRPC要求的请求实例 const request = new LogRequest(); // 给数组字段赋值,具体setter方法名以你本地生成的pb代码为准,常见命名是setXxxList request.setObjectUuidList(reqBody.object_uuid ?? []); request.setSize(reqBody.size ?? 0); getLoggerServiceClient().getLogsForObjects( request, (err, response) => { if (err) { logger.warn(`error getLogsForObjects: ${JSON.stringify(err)}`); return res.status(500).json({ error: err }); } logger.info(`success getLogsForObjects: ${JSON.stringify(response)}`); // 你原来的状态码逻辑写反了,拿到正常响应应该返回200,不是500 return res.status(200).json(response); }, ); };
补充排查点
- 先打日志确认Next.js层收到的请求体本身是正常的:打印
_req.body的内容和类型,Next.js默认会对JSON请求做body解析,这种情况下_req.body本身就是JS对象,不需要再手动调用JSON.parse,重复解析会抛出异常,也可能导致字段异常。 - 如果你用的是动态stub、不需要静态生成pb类的调用模式,检查字段名的下划线/驼峰映射问题,部分gRPC JSON转码实现会自动把snake_case的proto字段名转成camelCase,可以尝试把传参里的
object_uuid改成objectUuid测试。但优先用静态生成的消息类构造请求,能完全规避这类字段映射、类型不匹配的问题。
内容的提问来源于stack exchange,提问作者user3215374
相关产品推荐
相关产品推荐

