Gokit:在传输层验证request/payload
Gokit: Validate request/payload in transport layer
我正在使用 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 不是有效数字,return 400 Bad Request
来自此处的响应。
但是因为我在这个函数中没有 ResponseWriter 引用,所以我不知道该怎么做。
我正在关注 go-kit 文档中的这个示例
https://gokit.io/examples/stringsvc.html
request/payload 仅应在传输层中验证并且仅当 request/payload 有效时才应调用服务层是否是一个有效的假设?如果是,在本例中如何操作?
不能 100% 确定这是否也适用于 go-kit
grpc:
您有一个错误 return 变量。用它来表示有问题。在 go grpc 模块中有一个 status package 到 return 错误状态代码。如果你 return 一个带有状态代码的错误,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 使用 different status codes. In Go they are located in the codes package。
您可以使用 returns 服务器选项的 ServerErrorEncoder(可以在 github.com/go-kit/kit/transport/server.go 中找到)。
基本上在您的传输层中,除了 Decode 和 Encode 函数之外,您还可以定义一个 YourErrorEncoderFunc() 函数,如下所示。这将捕获传输层中抛出的任何错误。
YourErrorEncoderFunc(_ context.Context, 错误错误, 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...,
))
如果您的请求验证无效,这将在传输层停止,并根据您在 YourErrorEncoderFunc() 中编写的任何格式在 http 响应中抛出错误。
我正在使用 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 不是有效数字,return 400 Bad Request
来自此处的响应。
但是因为我在这个函数中没有 ResponseWriter 引用,所以我不知道该怎么做。
我正在关注 go-kit 文档中的这个示例 https://gokit.io/examples/stringsvc.html
request/payload 仅应在传输层中验证并且仅当 request/payload 有效时才应调用服务层是否是一个有效的假设?如果是,在本例中如何操作?
不能 100% 确定这是否也适用于 go-kit
grpc:
您有一个错误 return 变量。用它来表示有问题。在 go grpc 模块中有一个 status package 到 return 错误状态代码。如果你 return 一个带有状态代码的错误,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 使用 different status codes. In Go they are located in the codes package。
您可以使用 returns 服务器选项的 ServerErrorEncoder(可以在 github.com/go-kit/kit/transport/server.go 中找到)。
基本上在您的传输层中,除了 Decode 和 Encode 函数之外,您还可以定义一个 YourErrorEncoderFunc() 函数,如下所示。这将捕获传输层中抛出的任何错误。
YourErrorEncoderFunc(_ context.Context, 错误错误, 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...,
))
如果您的请求验证无效,这将在传输层停止,并根据您在 YourErrorEncoderFunc() 中编写的任何格式在 http 响应中抛出错误。