0

我正在使用 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中的这个示例

仅在传输层中验证请求/有效负载并且仅在请求/有效负载有效时才应调用服务层是一个有效的假设吗?如果是,在这个例子中怎么做?

4

2 回答 2

1

不是 100% 确定这是否也适用于go-kitgrpc:

您有一个错误返回变量。用它来表示有问题。在 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 中,它们位于代码包中。

于 2021-01-25T11:03:11.630 回答
0

您可以使用返回服务器选项的 ServerErrorEncoder(可以在 github.com/go-kit/kit/transport/server.go 中找到)。基本上在您的传输层中,除了 Decode 和 Encode 函数之外,您还可以定义一个 YourErrorEncoderFunc() 函数,如下所示。这将捕获传输层中抛出的任何错误。
YourErrorEncoderFunc(_ context.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...,
))

如果您的请求验证无效并根据您在 YourErrorEncoderFunc() 中编写的任何格式在 http 响应中抛出和错误,这将在传输层停止。

于 2021-01-27T13:05:30.720 回答