在微服务的调用过程中,context是贯穿整个流程的,所以我们希望可以在context中传递一些比较常见的信息,如cookie,用户的登录信息,平台或者版本等信息,这时候我们可以将其放在一个结构体中,然后塞入context里面
// Common 客户端传过来的通用参数,有下面这些字段。结构体中只包含常用的几个字段,其它字段可以通过context.Value()取
type Common struct {
Cookie string
UIN int64 // 用户身份编号整型表示
// 根据业务增加
}
和web或者客户端约定好,将需要的信息放到请求头中带过来即可
package middleware
import (
context "context"
"fmt"
myCtx "blog/comm/ctx"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
)
/**
登录的中间件
*/
func LoginMiddleWare(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (interface{}, error) {
c, err := loginHandler(ctx, req)
if err != nil {
return nil, err
}
reply, err := handler(c, req)
return reply, err
}
}
func loginHandler(ctx context.Context, r interface{}) (context.Context, error) {
log.Debug("中间件执行")
var comm myCtx.Common
if header, ok := transport.FromServerContext(ctx); ok {
for _, key := range header.RequestHeader().Keys() {
fmt.Printf("key:%s value:%s\n", key, header.RequestHeader().Get(key))
switch key {
case "cookie":
comm.Cookie = header.RequestHeader().Get(key)
case "Authorization":
comm.Cookie = header.RequestHeader().Get(key)
default:
fmt.Printf("key:%s value:%s\n", key, header.RequestHeader().Get(key))
}
}
} else {
return ctx, fmt.Errorf("invalid request")
}
ctx = context.WithValue(ctx, "comm", comm)
return ctx, nil
}
然后在接口中可以读取这个结构体中的数据并用于业务处理中
func (impl *ArticleImpl) GetArticleInfo(ctx context.Context, req *v1.GetArticleInfoReq) (*v1.GetArticleInfoRsp, error) {
//job := biz.NewArticleJob(impl.log, ctx, req)
//if err := job.FetchData(); err != nil {
// impl.log.Error("fetch data failed! err:%+v", err)
// return nil, err
//}
//return job.Compose(), nil
v := ctx.Value("comm")
log.Debugf("ctx comm value:%+v", v)
log.Infof("req:%+v", req)
rsp, err := rpc.GetUserInfo(ctx, "222")
if err != nil {
log.Errorf("rpc.GetUserInfo failed! err:%+v", err)
return nil, err
}
log.Debugf("rsp:%+v", rsp)
return &v1.GetArticleInfoRsp{
ArticleInfo: &v1.ArticleInfo{
Id: req.Id,
Title: "我的标题",
Content: rsp.Nick,
PublishTime: time.Now().Format("2006-01-02 15:04:05"),
Uin: rsp.Uin,
},
}, nil
}
网友评论