繁体   English   中英

返回 Grpc 验证错误的更好方法是什么

[英]What is a better way to return a Grpc validation error

我想知道 grpc 服务中是否有字段验证的模式。

我知道 RpcException 有 metadata trailers 属性,我可以添加关于我的错误的额外信息。

我的问题是:有规律可循吗? 如果不是,下面哪个例子更符合预期。

示例 1:

Metadata trailers = new Metadata();
trailers.Add("Name", "is required");
trailers.Add("Age", "is required");
trailers.Add("Age", "must be over 21");
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid Argument"), trailers, "One or more errors");

示例 2:

Metadata trailers = new Metadata();
trailers.Add("errors", @"{""Name"":[""Is required""],""Age"":[""Is required"",""must be over 21""]}");
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid Argument"), trailers, "One or more errors");

我想接受此响应并在需要时使用 RFC 7807 规范将其转换为 json

我不熟悉 C# API,但我可以谈谈 gRPC API,也许它可以帮助您实现 C#。

gRPC 错误 model错误 model 在逻辑上是由google.rpc.Status定义的,它的一个实例在 API 错误发生时返回给客户端。 下面的代码片段展示了错误model的总体设计,出错时返回:

package google.rpc;

message Status {

  // A simple error code that can be easily handled by the client. The
  // actual error code is defined by `google.rpc.Code`.
  int32 code = 1;

  // A developer-facing human-readable error message in English. It should
  // both explain the error and offer an actionable resolution to it.
  string message = 2;

  // Additional error information that the client code can use to handle
  // the error, such as retry delay or any business possible errors
  repeated google.protobuf.Any details = 3;

}

您应该使用详细信息字段将额外信息传递给错误。 例如,对于InvalidArgument ,您应该传递带有字段违规的BadRequest object

像(Golang 代码,希望它对你有意义)

st := status.New(codes.InvalidArgument, "invalid username")
v := &BadRequest_FieldViolation{
    Field: "username",
    Description: "The username must only contain alphanumeric characters",
}
br := &BadRequest{}
br.FieldViolations = append(br.FieldViolations, v)
st, _ := st.WithDetails(br)

是 gRPC 提供的 object 的列表,如果其中任何一个适合您的场景,您可以将其用作错误详细信息,您可以随时创建自己的场景。

在详细信息字段中返回与业务相关的内容是一种很好的做法。 就像一个已知的错误代码。 这样您的客户就可以对问题做出回应。

errorDetail := &BusinessError{
  ErrorCode: CODE,
  ErrorMessage: "Failed to filter hotel rooms",
}
st := status.New(codes.Internal, "Something went wrong :( ")
st, _ = st.WithDetails(errorDetail)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM