英文:
How to use grpc status code and build response accordingly to the client?
问题
我正在翻译你的内容,请稍等片刻。
我想知道在将 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("无法检索到客户端信息,clientId:%d", clientId)
// 这样返回是否正确?
return nil, status.Error(codes.NotFound, msg)
}
resources := request.GetResources()
if len(resources) == 0 {
// 这样返回是否正确?
err := status.Error(codes.InvalidArgument, "值不能为空。(参数 'resources')")
return nil, err
}
return us.GenerateCustomerInfo(clientId, resources)
}
我的 proto 文件非常简单 -
service CustomerService {
rpc FetchResponse(CustomerRequest) returns (CustomerResponse) {};
}
message CustomerRequest {
string resources = 1;
}
message CustomerResponse {
string proc = 1;
string data = 2;
}
GenerateCustomerInfo
方法将同时返回 CustomerResponse
和 error
。但如果出现错误,那么状态码是什么?我正在尝试弄清楚人们在返回 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.
答案1
得分: 3
这样做完全没问题:
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 { // 发生了错误
fmt.Printf("Code: %d, Message: %s\n", s.Code(), s.Message())
}
GenerateCustomerInfo
方法将同时返回CustomerResponse
和error
。但如果发生错误,应返回什么状态码?
对于 GenerateCustomerInfo
,我们没有太多信息来进行复现,但我认为你应该返回类似以下的内容:
return &custPbV1.CustomerResponse{
Proc: "YOUR_PROC",
Data: "YOUR_DATA",
}, nil
通过在错误中返回 nil
,你将向客户端显示没有错误,并且在之前的代码中,ok
将为 false
。
在响应对象中添加错误属性是一个好主意吗?
对于这个问题,你确实可以添加一个错误属性,但是否有必要呢?你已经有了状态码和消息,添加错误属性只会不必要地增加有效载荷的大小。
但是如果
GenerateCustomerInfo
返回任何错误,我应该返回什么状态码?我需要自己定义吗?
假设 GenerateCustomerInfo
的一个潜在实现如下:
func GenerateCustomerInfo() (*pb.CustomerResponse, error) {
// 一些代码
if err {
st := status.Error(codes.Internal /*或其他*/, "一条消息")
return nil, err
}
return &pb.CustomerResponse{
Proc: "",
Data: "",
}, nil
}
它将返回一个 CustomerResponse
或 nil
,这完全符合父函数的需求。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论