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

使用gRPC时响应中为何无法获取null值?Nest.js微服务问题

问题原因与解决方案:Nest.js gRPC响应丢失Null值

原因分析

gRPC依赖的Protobuf 3默认不会序列化值为默认值的字段,string类型的默认值是空字符串,而null会被Protobuf视为等价于默认值,因此在序列化阶段会被直接丢弃,不会被包含在传输的二进制数据中。你在Service Y中打印的是未经过序列化的JavaScript对象,所以能看到null字段,但经过gRPC的序列化-反序列化流程后,这些null字段就不会出现在Service X的响应里了。

解决方案

1. 使用Protobuf可选类型显式支持Null

修改proto文件,将需要保留null的字段替换为google.protobuf.StringValue(专门用于处理可空字符串):

import "google/protobuf/wrappers.proto";

message userModel {
  string name = 1;
  string email = 2;
  google.protobuf.StringValue phone = 3;
}

message userResponse {
  repeated userModel user = 1;
}

在Nest.js代码中,给该字段赋值时:

  • 非null值:{ value: "123456789" }
  • null值:{ value: null }
    这样gRPC会显式传递null状态,Service X就能接收到该字段。

2. 调整gRPC客户端序列化配置

在Service X的gRPC客户端配置中,开启defaults选项,强制保留所有默认值字段(包括被视为默认值的null转换后的空字段):

import { ClientOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';

export const grpcClientOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'your-package', // 替换为你的proto包名
    protoPath: join(__dirname, './user.proto'), // 替换为你的proto路径
    loader: {
      keepCase: true,
      defaults: true, // 开启后会保留所有默认值字段
      arrays: true,
      objects: true,
    },
  },
};

注意:此方案会保留所有类型的默认值字段(比如数字0、空数组等),需根据业务场景判断是否适用。

3. 手动转换Null为默认值

如果不想修改proto文件,可以在Service Y返回响应前,将null字段转换为对应类型的默认值(比如string类型转空字符串):

// Service Y中处理响应的代码
const rawUsers = await yourDataSource.find();
const responseUsers = rawUsers.map(user => ({
  name: user.name,
  email: user.email,
  phone: user.phone ?? '', // 将null转为空字符串
}));

return { data: responseUsers };

这样序列化时字段会被保留,Service X就能接收到该字段(值为空字符串)。

内容的提问来源于stack exchange,提问作者V. Benavides

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:58:15