无法读取打字稿/JavaScript gRPC google.protobuf.Struct

问题描述

我有一个 TypeScript 服务器试图使用 Struct 读取一个 JSON 对象,但它似乎只对包含“字段”键的对象部分工作,然后期望一个对象作为值。尽管如此,Struct 应该适用于任何 JSON 对象。

使用 BloomrPC 我正在尝试以下消息:

{
  "payload": {
    "fields": {
      "Hello": {
        "whatever": 0
      }
    }
  }
}

服务器读取:

{ fields: { Hello: {} } }

如果我发送:

{
  "payload": {
    "anotherfield": {
      "HelloWorld": {
        "whatever": 0
      }
    }
  }
} 

我在服务器上得到一个空对象。

简化后的 protobuf 文件如下所示:

Syntax = "proto3";

import "google/protobuf/struct.proto";

// The service deFinition.
service TestTicketService {
  rpc UpdateTicket (UpdateTicketRequest) returns (UpdateTicketResponse);
}

// The request message containing the required ticket information.
message UpdateTicketRequest {
    string ticketId = 1;
    google.protobuf.Struct payload = 2;
}

// The response message containing any potential error message
message UpdateTicketResponse {
  string error = 1;
}

知道为什么 google/protobuf/struct.proto 没有按预期工作吗?

解决方法

结构的想法是您可以存储任意数据 - 但只能存储简单类型:null、数字、字符串、bool、数组和对象。

这完美地映射到 JSON,这并非偶然。 google.protobuf.Struct 消息有一个特殊的 JSON 表示:

Struct 的 JSON 表示是 JSON 对象。

这样你就可以将任何 JSON 字符串解析成一个 protobuf Struct,当再次序列化为 JSON 时,你也会再次得到相同的 JSON 字符串。

需要注意的是,解析后的 Struct 在内存中的表示不等于 JSON 对象。 Protobuf 没有动态字段,必须以更复杂的方式表示 JSON 数据。这就是 struct.proto 定义一些其他类型的原因。

当您想在 JavaScript 中创建 Struct 时,创建您想要的 JSON 对象可能是最简单的方法:

var jsonObject = {foo: "bar"};
var jsonString = JSON.stringify(jsonObject);

现在你可以从这个 jsonObject 或 jsonString 解析你的 Struct 并将结果 Struct 作为字段值放在另一个 protobuf 消息中。

由于您已经在使用 TypeScript,因此可能值得查看 protobuf 的替代 TypeScript 实现之一。 我是 protobuf-ts 的作者。创建结构非常简单:

let struct = Struct.fromJson({foo: "bar"});
,

真正让我困惑的是,我试图传递普通的 JSON 对象并期望读取它们。重点是从客户端来看,JSON 对象需要以非常特定的方式进行编码。

例如:

"payload": {
    "fields": {
      "name": {
        "stringValue": "joe"
      },"age": {
        "numberValue": 28
      }
    }
  }

您可以通过查看此处的 Struct proto 文件来确定消息的格式:https://googleapis.dev/nodejs/asset/latest/v1_doc_google_protobuf_doc_struct.js.html

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...