为了账号安全,请及时绑定邮箱和手机立即绑定

如何强制 Protobuf 3 字段?

如何强制 Protobuf 3 字段?

Go
守着星空守着你 2022-06-06 15:26:23
我正在使用 GRPC/proto-buffers 在 GoLang 中编写我的第一个 API 端点。我对 GoLang 比较陌生。以下是我为测试用例编写的文件package my_packageimport (    "context"    "testing"    "github.com/stretchr/testify/require"    "google.golang.org/protobuf/types/known/structpb"    "github.com/MyTeam/myproject/cmd/eventstream/setup"    v1handler "github.com/MyTeam/myproject/internal/handlers/myproject/v1"    v1interface "github.com/MyTeam/myproject/proto/.gen/go/myteam/myproject/v1")func TestEndpoint(t *testing.T) {    conf := &setup.Config{}    // Initialize our API handlers    myhandler := v1handler.New(&v1handler.Config{})    t.Run("Success", func(t *testing.T) {        res, err := myhandler.Endpoint(context.Background(), &v1interface.EndpointRequest{            A: "S",            B: &structpb.Struct{                Fields: map[string]*structpb.Value{                    "T": &structpb.Value{                        Kind: &structpb.Value_StringValue{                            StringValue: "U",                        },                    },                    "V": &structpb.Value{                        Kind: &structpb.Value_StringValue{                            StringValue: "W",                        },                    },                },            },            C: &timestamppb.Timestamp{Seconds: 1590179525, Nanos: 0},        })        require.Nil(t, err)        // Assert we got what we want.        require.Equal(t, "Ok", res.Text)    })}这是在上面包含的文件EndpointRequest中定义对象的方式:v1.go// An v1 interface Endpoint Request object.message EndpointRequest {  // a is something.  string a = 1 [(validate.rules).string.min_len = 1];  // b can be a complex object.  google.protobuf.Struct b = 2;  // c is a timestamp.  google.protobuf.Timestamp c = 3;}上面的测试用例似乎工作正常。我设置了有效地使参数成为a强制性的验证规则,因为它要求它a至少是一个字符串。因此,如果您省略a,端点将返回 400。但现在我想确保端点返回 400 如果c或被b省略。我怎样才能做到这一点?在 Protobufs 3 中,他们去掉了required关键字。那么如何检查是否传入了非字符串参数并做出相应的反应呢?
查看完整描述

2 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

中删除了必填字段proto3这是 github 问题,您可以在其中阅读详细说明为什么这样做。这是摘录:

我们在 proto3 中删除了必填字段,因为必填字段通常被认为是有害的并且违反了 protobuf 的兼容性语义。使用 protobuf 的整个想法是,它允许您从协议定义中添加/删除字段,同时仍然与较新/较旧的二进制文件完全向前/向后兼容。必填字段打破了这一点。您永远不能安全地将必填字段添加到 .proto 定义中,也不能安全地删除现有的必填字段,因为这两个操作都会破坏线路兼容性

IMO,这是一个有问题的决定,显然我并不孤单,谁在这么想。最终决定应该留给开发商。


查看完整回答
反对 回复 2022-06-06
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

简短的版本:你不能。

required被删除主要是因为它使更改向后不兼容。尝试使用验证选项重新实现它并不是那么激烈(更改更容易),但会遇到一些缺点,如您所见。

相反,将验证排除在原型定义之外,并将其移至应用程序本身。任何时候你收到一条消息,你都应该检查它的内容(这在发生的时候也是如此required)。选项提供的简单验证或required足够的情况很少见。


查看完整回答
反对 回复 2022-06-06
  • 2 回答
  • 0 关注
  • 218 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信