NodeJS中google.protobuf.Struct无法正常工作的问题排查
解决Node.js中gRPC使用google.protobuf.Struct收发数据的问题
你的问题核心是没有遵循google.protobuf.Struct的protobuf结构规范,直接传入/返回普通JS对象会导致gRPC解析错误,进而出现数据无法读取或响应为空的情况。
问题根源
google.protobuf.Struct并非普通JSON对象,它有固定的protobuf定义结构:
message Struct { map<string, Value> fields = 1; } message Value { oneof kind { NullValue null_value = 1; string string_value = 2; int64 number_value = 3; bool bool_value = 4; Struct struct_value = 5; ListValue list_value = 6; } }
直接传递普通JS对象,gRPC无法自动映射到这个结构,导致数据丢失或解析失败。
修正方案
需要借助google-protobuf包提供的工具方法,在普通JS对象和Struct格式之间做转换。
1. 确保依赖安装
虽然@grpc/grpc-js依赖google-protobuf,但需要直接引用其工具类:
npm install google-protobuf
2. 客户端代码修正
使用Struct.fromJavaScript()将普通JS对象转为Struct格式,接收响应时用toJavaScript()转回JS对象:
const { Struct } = require('google-protobuf/google/protobuf/struct_pb'); function findById(id) { // 把普通JS对象转换为Struct格式 const bodyStruct = Struct.fromJavaScript({ id: "xxxxxx" }); client?.findById({ body: bodyStruct }, (err, response) => { if (err) { console.log(err); return; } // 将返回的Struct转换为普通JS对象 let workspace = response.workspace.toJavaScript(); console.log(workspace); // 现在能正确拿到{name: "Sample Workspace Name", id: "Sample Workspace Id"} }); }
3. 服务端代码修正
读取请求时将Struct转为JS对象,返回响应时将JS对象转为Struct:
const { Struct } = require('google-protobuf/google/protobuf/struct_pb'); function findById(call, callback) { // 将请求中的Struct转换为普通JS对象 const bodyObj = call.request.body.toJavaScript(); let { id } = bodyObj; // 现在能正确获取到id值 let sampleWorkspaceSpace = { "name": "Sample Workspace Name", "id": "Sample Workspace Id" }; // 把返回的JS对象转换为Struct格式 const workspaceStruct = Struct.fromJavaScript(sampleWorkspaceSpace); callback(null, { workspace: workspaceStruct }); }
补充:手动构造Struct(不推荐)
如果不想用工具方法,也可以手动构造符合Struct结构的对象(繁琐,不建议):
// 手动构造包含id的Struct const bodyStruct = { fields: { id: { stringValue: "xxxxxx" // 根据数据类型选择对应的Value字段,如number_value、bool_value等 } } };
内容的提问来源于stack exchange,提问作者ololo
相关产品推荐
相关产品推荐

