【问题标题】:Google Cloud Endpoints: Transcoding messages with protobuf.Any fieldsGoogle Cloud Endpoints:使用 protobuf.Any 字段对消息进行转码
【发布时间】:2018-06-11 22:28:02
【问题描述】:

我有一个 grpc 服务,该服务将包含 protobuf.Any 类型字段的消息作为输入,但我不知道如何为它编写正确的 json 输入。我在 GKE 上运行,云端点 ESP 和我的服务在同一个 pod 中运行。

原型看起来像:

message AnyArray {
    repeated google.protobuf.Any value = 1;
}
message Metric {
    string metric = 1;
    int64 timestamp = 2;
    double value = 3;
    map<string, AnyArray> metadata = 4;
}

我为输入 json 尝试了多种组合,但没有成功,大多数时候云端点返回“原始字段不重复,无法启动列表”。失败的例子:

{
    "metadata": {
        "sample-key": {
            "value": [1, "one"]
        }
    },
    "metric": "request-count",
    "timestamp": 1528425789,
    "value": 0
}

{
    "metadata": {
        "sample-key": {
            "value": [{
                "@type": "type.googleapis.com/google.protobuf.Duration",
                "value": "1.212s"
            }, {
                "@type": "type.googleapis.com/google.protobuf.Duration",
                "value": "1.212s"
            }]
        }
    },
    "metric": "request-count",
    "timestamp": 1528425789,
    "value": 0
}

来自 ESP 的响应

{
    "code": 3,
    "message": "metadata[0].value: Proto field is not repeating, cannot start list.",
    "details": [{
        "@type": "type.googleapis.com/google.rpc.DebugInfo",
        "stackEntries": [],
        "detail": "internal"
    }]
}

任何帮助将不胜感激。

谢谢!

【问题讨论】:

    标签: google-cloud-endpoints


    【解决方案1】:

    google.protobuf.Any 表示任何原始消息类型,因此您的第一个示例不起作用。对于第二个例子,google.protobuf.Duration 有一个特殊的 JSON 映射,所以下面的例子应该可以工作:

    {
        "metadata": {
            "sample-key": {
                "value": [{
                    "@type": "type.googleapis.com/google.protobuf.Duration",
                    "value": "1.212s"
                }, {
                    "@type": "type.googleapis.com/google.protobuf.Duration",
                    "value": "1.212s"
                }]
            }
        },
        "metric": "request-count",
        "timestamp": 1528425789,
        "value": 0
    }
    

    请注意,您必须在提供的 Cloud Endpoints 服务的原型描述符集中包含 google.protobuf.Any 的所有可能的原型消息类型,否则它将无法转换未知类型。

    另一种可能的方法是将google.protobuf.Struct 用于您的元数据,这消除了上述限制,但您必须将其转换为您的 gRPC 服务中的预期类型。

    【讨论】:

    • 感谢您的回复。我尝试了您提供的修改,但仍然收到相同的错误: { "code": 3, "message": "metadata[0].value: Proto field is not repeating, cannot start list.", "details": [ { "@type": "type.googleapis.com/google.rpc.DebugInfo", "stackEntries": [], "detail": "internal" } ] } 还有其他建议吗?
    • 另外,虽然我使用 Any,但我的意图是只支持标量类型。
    • 如果只想支持标量类型,那么不要使用google.protobuf.Any,只需将metadata类型改为google.protobuf.Struct即可。那么您提供的第一个示例应该可以工作。
    【解决方案2】:

    按照@lizan 的建议,使用 protobuf.Struct 代替 protobuf.Any 解决了我的问题。谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-28
      • 2013-11-11
      • 2018-12-29
      • 1970-01-01
      • 2013-12-21
      • 2019-11-06
      • 2020-01-02
      相关资源
      最近更新 更多