Go Kit日志中间件context与request参数传递机制疑问
Go Kit中间件参数传递逻辑解析
你的核心疑问是中间件里接收ctx和request的函数,参数是怎么传进来的?咱们结合Go Kit的调用链路一步步拆解:
1. 先明确Endpoint的本质
Go Kit里的endpoint.Endpoint是一个标准函数类型:
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
不管是你的业务端点MakeTotalRetailPriceEndpoint,还是中间件包裹后返回的函数,本质上都是这个类型的函数——这是中间件能嵌套的基础。
2. 参数的源头:httptransport.Server
你用httptransport.NewServer创建的HTTP服务端,是整个调用链的发起者:
当有HTTP请求进来时,它会依次做这几件事:
- 调用你传入的
decodeTotalRetailPriceRequest,把原始HTTP请求(比如http.Request)解析成业务层需要的request对象; - 生成请求上下文
ctx(基于HTTP请求自带的context,可能包含超时、请求ID、头部信息等); - 调用你组装好的
retailEndpoint(也就是被日志中间件包裹后的端点函数),把刚才生成的ctx和解析后的request作为参数传进去。
3. 中间件的执行链路
再看你组装端点的代码:
retailEndpoint = MakeTotalRetailPriceEndpoint(svc) retailEndpoint = LogTotalRetailPriceEndpoint(logger)(retailEndpoint)
- 第一行:
MakeTotalRetailPriceEndpoint返回的是你的业务逻辑端点,负责处理具体的价格计算。 - 第二行:
LogTotalRetailPriceEndpoint(logger)返回一个endpoint.Middleware(本质是func(next endpoint.Endpoint) endpoint.Endpoint),把业务端点传进去后,得到一个新的Endpoint函数——就是你中间件里那个匿名函数:func(ctx context.Context, request interface{}) (interface{}, error) { logger.Log("endpoint", "TotalRetailPriceEndpoint", "msg", "Calling endpoint") defer logger.Log("endpoint", "TotalRetailPriceEndpoint", "msg", "Called endpoint") return next(ctx, request) }
这个新的函数就是最终被httptransport.Server调用的入口,所以ctx和request是Server直接传进来的。中间件做完日志逻辑后,再把这两个参数原封不动传给next(也就是你的业务端点),完成整个调用链。
简单说:参数是HTTP服务端(httptransport.Server)生成并传入中间件的,中间件只是做一层拦截处理,再把参数传递给后续的业务逻辑。
内容的提问来源于stack exchange,提问作者needhelp
相关产品推荐
相关产品推荐

