【发布时间】:2018-07-17 19:48:12
【问题描述】:
我有一个在 Spring 上运行并定义多个 gRPC 端点的 Java 应用程序。这些端点旨在从多个客户端进行查询,其中一个在 PHP 中,因此我使用了 gRPC 的 PHP 库。现在我想知道如何在出现无效请求的情况下从服务器正确获取元数据,该元数据主要包含由 Java 验证器构建的约束违规,并转换为 gRPC FieldViolation 对象的集合。在此示例中,服务器应该返回一个字段违规作为元数据,键为“violationKey”,描述为“violationDescription”:
try {
// doStuff
} catch (ConstraintViolationException e) {
Metadata trailers = new Metadata();
trailers.put(ProtoUtils.keyForProto(BadRequest.getDefaultInstance()), BadRequest
.newBuilder()
.addFieldViolations(FieldViolation
.newBuilder()
.setField("violationKey")
.setDescription("violationDescription")
.build()
)
.build()
);
responseObserver.onError(Status.INVALID_ARGUMENT.asRuntimeException(trailers));
}
在 PHP 端,这是检索元数据的实现:
class Client extends \Grpc\BaseStub
{
public function callService()
{
$call = $this->_simpleRequest(
'MyService/MyAction',
$argument,
['MyActionResponse', 'decode'],
$metadata, $options
);
list($response, $status) = $call->wait();
var_dump($status->metadata); // A
var_dump($call->getMetadata()); // B
}
}
结果:“A”输出一个空数组,“B”输出正确的元数据,格式如下:
array(1) {
["google.rpc.badrequest-bin"]=>
array(1) {
[0]=>
string(75) "
I
testALicense plate number is not in a valid format for country code FR"
}
}
为什么状态中的元数据是空的,为什么$call->getMetadata()检索到的元数据是这样格式化的(“I”后跟违规键,然后是“A”,最后是违规描述)?如何避免对这个元数据客户端进行可能繁琐的转换?
【问题讨论】: