我使用Github的grpc-gateway项目从gRPC规范自动生成REST API。在此REST API中,我想支持ETag
标头和304 Not Modified响应。
据我了解,通常您会在gRPC服务器中创建一个具有特定状态代码的响应,然后该状态代码将由grpc-gateway转换为HTTP状态代码。但是,由于标准gRPC并不真正支持缓存概念,因此没有映射到HTTP 304状态代码的gRPC状态代码。
使用grpc-gateway,似乎可以在gRPC状态代码为错误代码时自定义HTTP状态代码(覆盖runtime.HTTPError函数)。但是,当gRPC repsonse代码正常时,我还没有找到任何方法来自定义HTTP响应代码。
那么,有没有推荐的方法来实现这个目标?
答案 0 :(得分:0)
以下是使用自定义转发器实现基本etag和304响应的示例。
您可以参考这些directions进行设置,然后按以下方式实施该方法:
func forwardGetPost(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
// add cache-control rules for this proxy endpoint
w.Header().Add("Cache-Control", "max-age=60")
// create an etag
// (when the response represents some entity from the db it may have a last edited timestamp)
p := resp.(*Post)
etag := fmt.Sprintf("W/%q", p.GetLastEdited())
w.Header().Add("ETag", etag)
// check whether the request provides an etag
inm := req.Header.Get("If-None-Match")
if inm != "" {
if inm == etag {
w.WriteHeader(http.StatusNotModified)
}
}
runtime.ForwardResponseMessage(ctx, mux, marshaler, w, req, resp, opts...)
}
这不会阻止代理向grpc服务器发出请求,但是当etags匹配时,它会阻止将这些字节发送回客户端。