我正在使用go-kit创建RPC端点。我要创建一个这样的端点
httptransport.NewServer(
endPoint.MakeGetBlogEndPoint(blogService),
transport.DecodeGetBlogRequest,
transport.EncodeGetBlogResponse
下面是我的DecodeGetBlogRequest函数
func DecodeGetBlogRequest(c context.Context, r *http.Request) (interface{}, error) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
return nil, err
}
req := endPoint.GetBlogRequest{
ID: id,
}
return req, nil
}
我想做的是验证此函数中的HTTP请求,如果发现无效,则仅从这里发送带有有效错误代码的响应,而不将其传递给服务层。即,如果ID不是一个有效的数字,从这里返回400 Bad Request
响应。
但是由于我在这个函数中没有ResponseWriter引用,我不确定如何做到这一点。
我遵循这个例子从go-kit文档https://gokit.io/examples/stringsvc.html
请求/有效负载应该只在传输层验证,而服务层应该只在请求/有效负载有效时调用,这是一个有效的假设吗?如果是,在本例中如何配置?
您可以使用ServerErrorEncoder返回服务器选项(可以在github.com/go-kit/kit/transport/server.go中找到)。基本上,在传输层中,除了Decode和Encode函数之外,还可以定义yourerrorrencoderfunc()函数,如下所示。这将捕获传输层中抛出的任何错误。
你的错误的coderfunc(_上下文。Context, err error, w http.ResponseWriter).
您需要在端点注册中附加此函数作为选项,如:
ABCOpts := []httptransport.ServerOption{
httptransport.ServerErrorEncoder(YourErrorEncoderFunc),
}
r.Methods("GET").Path("/api/v1/abc/def").Handler(httptransport.NewServer(
endpoints.GetDataEndpoint,
DecodeGetRequest,
EncodeGetResponse,
ABCOpts...,
))
如果你的请求验证无效,这将在传输层停止,并在基于你在yourerrorrencoderfunc()中编写的任何格式的http响应中抛出和错误。
不能100%确定这是否也适用于go-kit
grpc:
有一个错误返回变量。用这个来表示有问题。在go grpc模块中有一个状态包用于返回带有状态码的错误。如果返回一个带有状态码的错误,grpc层将从错误中获取代码并将其发送回去。
例如:
func DecodeGetBlogRequest(c context.Context, r *http.Request) (interface{}, error) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
req := endPoint.GetBlogRequest{
ID: id,
}
return req, nil
}
还要注意,grpc使用不同的状态码。在Go中,它们位于codes包中。