如何使用 grpc 状态代码并根据客户端构建响应?

发布于 2025-01-11 06:44:52 字数 1377 浏览 0 评论 0原文

我想知道当我们发送回用户时处理 grpc 状态代码和响应的最佳方法是什么?

func (us *customerService) FetchResponse(ctx context.Context, request *custPbV1.CustomerRequest) (*custPbV1.CustomerResponse, error) {
    meta := service.MetadataFromContext(ctx)
    clientId := meta.ClientId
    if clientId <= 0 {
        msg := fmt.Sprintf("could not retrieve client info for clientId:%d", clientId)
        // is this right way to return it?
        return nil, status.Error(codes.NotFound, msg)
    }

    resources := request.GetResources()
    if len(resources) == 0 {
        // is this right way to return it?
        err := status.Error(codes.InvalidArgument, "value cannot be null. (Parameter 'resources')")
        return nil, err
    }

    return us.GenerateCustomerInfo(clientId, resources)
}

我的原型非常简单 -

service CustomerService {
   rpc FetchResponse(CustomerRequest) returns (CustomerResponse) {};
}

message CustomerRequest {
   string resources = 1;
}

message CustomerResponse {
   string proc = 1;
   string data = 2;
}

GenerateCustomerInfo 方法将返回 CustomerResponseerror 两者。但如果出现错误,那么状态码会是什么?我试图弄清楚人们在返回 grpc 状态代码和响应给用户时遵循的标准是什么。是否必须将状态代码返回给客户端?

在响应对象中也有错误属性是个好主意吗?任何演示如何返回 grpc 状态和响应的最佳实践的示例都将对我有用。

I am wondering what is the best way to deal with grpc status code and response when we sent back to the user?

func (us *customerService) FetchResponse(ctx context.Context, request *custPbV1.CustomerRequest) (*custPbV1.CustomerResponse, error) {
    meta := service.MetadataFromContext(ctx)
    clientId := meta.ClientId
    if clientId <= 0 {
        msg := fmt.Sprintf("could not retrieve client info for clientId:%d", clientId)
        // is this right way to return it?
        return nil, status.Error(codes.NotFound, msg)
    }

    resources := request.GetResources()
    if len(resources) == 0 {
        // is this right way to return it?
        err := status.Error(codes.InvalidArgument, "value cannot be null. (Parameter 'resources')")
        return nil, err
    }

    return us.GenerateCustomerInfo(clientId, resources)
}

My proto is very simple -

service CustomerService {
   rpc FetchResponse(CustomerRequest) returns (CustomerResponse) {};
}

message CustomerRequest {
   string resources = 1;
}

message CustomerResponse {
   string proc = 1;
   string data = 2;
}

GenerateCustomerInfo method will return CustomerResponse and error both. But if there is a error then what status code it will be? I am trying to figure out what is the standard basically people follow while returning grpc status code and response back to user. Is it mandatory to return status code back to client or no?

Is it good idea to have error property in response object as well? Any example that demonstrates best practice on how to return grpc status and response back will be useful for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两人的回忆 2025-01-18 06:44:52

这样做是完全可以的:

err := status.Error(codes.InvalidArgument, "value cannot be null. (Parameter 'resources')")
return nil, err

这将告诉您的客户端存在错误,并且有了这些信息,客户端可以检查状态代码和状态消息,如下所示:

resp, err = server.FetchResponse(context.Background(), req)
s, ok := status.FromError(err)

if ok { // there is an error
   fmt.Printf("Code: %d, Message: %s\n", s.Code(), s.Message())
}

GenerateCustomerInfo 方法将返回 CustomerResponse 和错误。但如果出现错误,那么状态码会是什么?

对于 GenerateCustomerInfo,我们没有太多信息可以重现,但在我看来,您应该返回类似以下内容:

return &custPbV1.CustomerResponse{
    Proc: "YOUR_PROC",
    Data: "YOUR_DATA",
}, nil

通过在错误中返回 nil,您将向客户端显示没有错误,在前面的代码中给出的 ok 将为 false。

在响应对象中也有错误属性是个好主意吗?

为此,您绝对可以添加一个错误属性,但是有必要这样做吗?您已经可以拥有 StatusCode 和 Message。它只会不必要地增加有效负载的大小。

但是如果GenerateCustomerInfo返回任何错误,那么我应该返回什么状态代码?我也需要定义它吗?

给定 GenerateCustomerInfo 的潜在实现如下:

func GenerateCustomerInfo() (*pb.CustomerResponse, error) {
    // some code
    if err {
        st := status.Error(codes.Internal /*or other*/, "a message")
        return nil, err
    }

    return &pb.CustomerResponse{
        Proc: "",
        Data: "",
    }, nil
}

它基本上会返回 CustomerResponsenil 这完全是父函数所需要的。

This is totally fine to do it like this:

err := status.Error(codes.InvalidArgument, "value cannot be null. (Parameter 'resources')")
return nil, err

This will tell your client that there is an error and with that knowledge the client can check the status code and the status message as following:

resp, err = server.FetchResponse(context.Background(), req)
s, ok := status.FromError(err)

if ok { // there is an error
   fmt.Printf("Code: %d, Message: %s\n", s.Code(), s.Message())
}

GenerateCustomerInfo method will return CustomerResponse and error both. But if there is a error then what status code it will be?

For the GenerateCustomerInfo we don't have much info to reproduce but in my opinion you should just return something like:

return &custPbV1.CustomerResponse{
    Proc: "YOUR_PROC",
    Data: "YOUR_DATA",
}, nil

by returning nil in the error, you will show the client that there is no error and in the previous code give the ok will be false.

Is it good idea to have error property in response object as well?

for that, you definitely could add an error property, but is there any need for that? you can already have a StatusCode and a Message. It would just increase the size of your payload unnecessarily.

But if GenerateCustomerInfo return any error then what status code should I return back? Do I need to define that too?

Given an potential implementation of GenerateCustomerInfo like:

func GenerateCustomerInfo() (*pb.CustomerResponse, error) {
    // some code
    if err {
        st := status.Error(codes.Internal /*or other*/, "a message")
        return nil, err
    }

    return &pb.CustomerResponse{
        Proc: "",
        Data: "",
    }, nil
}

it will basically return either a CustomerResponse or nil which is totally what the parent function need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文