对于一个Golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《将gin gonic的数据传递到gRPC微服务》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!
问题内容我正在编写一个支持多个源的微服务(然后定义要连接到的数据库)。为了做到这一点,我需要例如原点。带有 gin 的服务器负责验证来源,rpc 微服务不验证任何内容。我唯一缺少的一点是如何将此元数据传递到上下文内的 rpc 服务。
我尽可能地简化了这个想法,实际情况要复杂得多,并且有超过 1 个值需要传递。将所有这些东西传递给所有函数是不值得讨论的,因为它会产生太多的开销
杜松子酒服务器
func originmiddleware() gin.handlerfunc {
return func(context *gin.context) {
origin := context.getheader("origin")
// add origin to the context
context.next()
}
}
func main(){
... // setup grpc etc
r.use(originmiddleware())
r.post("/login", user.login)
r.get("/getuser", user.get)
... // many other endpoints
r.run("localhost:8080")
}
微服务
func OriginInterceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
origin := ctx.Value("origin")
fmt.Println(origin)
... // get or create db connection whatsoever
return handler(ctx, req)
}
}
func main() {
... // setup
s := grpc.NewServer(grpc.UnaryInterceptor(MongoInterceptor()))
UserPB.RegisterUserServiceServer(s, &server{})
... // serve
}
我一直在尝试的事情
- 覆盖 gin 上下文似乎不可能
- 使用
.set
仅在“gin”服务器内部有效,但发送到 grpc 时所有值都会丢失
正确答案
我找到了一个可行的解决方案,但它不是最干净的。改进和批评都被广泛接受!
func togrpccontext(ctx *gin.context) context.context {
res := make(map[string]string)
for key, value := range ctx.keys {
switch v := value.(type) {
case string:
res[key] = v
}
}
return metadata.newoutgoingcontext(ctx, metadata.new(res))
}
每次调用任何 grpc 函数时,我都会使用此辅助函数包装上下文,例如:
user, err := UserPB.GetUser(ToGrpcContext(ctx), &UserPB.GetUserInput{...})
到这里,我们也就讲完了《将gin gonic的数据传递到gRPC微服务》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注编程网公众号,带你了解更多关于的知识点!