【问题标题】:Is it possible to check enum value in proto file?是否可以检查 proto 文件中的枚举值?
【发布时间】:2019-06-05 13:27:29
【问题描述】:

我想验证生成的 Java 代码中的枚举值。我有以下原型文件:

syntax = "proto3";

import "google/protobuf/empty.proto";

option java_multiple_files = true;
option java_package = "com.package";

package helloworld;

service SomeService {
    rpc DoAction (Request) returns (google.protobuf.Empty) { }
}

enum Currency {
    EUR = 0;
    GBP = 1;
    USD = 2;
}

message Request {
    string id = 1;
    Currency currency = 2;
}

我想在由protobuf 生成的代码中对 Currency 枚举进行一些验证,并在值不适用于提供的枚举时删除错误消息(例如:invalid currency)。有可能吗?

【问题讨论】:

    标签: java enums grpc grpc-java proto3


    【解决方案1】:

    您可以对其进行验证,但您也应该注意 Protobuf 枚举的细微差别。

    1. 始终为每个枚举包含一个 UNKNOWN = 0; 枚举值。当 Protobuf 不知道枚举值对应什么时,它会将其设置为默认值。这使您可以检测具有新代码的较新客户端何时使用服务器不理解的值。另外,如果该字段未设置,它自然等于UNKNOWN,让您检查该字段是否不存在。 (如果您确实想允许不存在的枚举,请将它们包装在 message{} 中)。

    2. 在您的服务器应用程序处理程序中,您应该检查客户端提供的支持值之一。如果它不是其中之一,您应该使用INVALID_ARGUMENT 状态代码使 RPC 失败:

        out: {
          switch (req.getCurrency()) {
            case EUR: 
            case GBP:
            case USD: break out;
            case UNKNOWN:
              responseObserver.onError(
                  Status.INVALID_ARGUMENT
                      .withDescription("bad currency " + req.getCurrency())
                      .asRuntimeException());
              return;
          }
          throw new AssertionError("missed case!");
        }
        // keep handling the request
    

    此代码检查代码是否为受支持的代码之一。如果有不支持的代码进来,会被UNKNOWN case 处理,并提前返回错误。如果您修改了原型并添加了更多案例,静态分析将捕获丢失的案例(或抛出 AssertionError)。请注意,如果客户端更新他们的原型,这不会发生。避免使用default 的情况,因为在修改 proto 时很容易漏掉它。或者,您可以将所有支持的案例放在一个地图中并检查它是否存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-12
      • 2015-02-12
      • 2017-10-03
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多