Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前置请求中间件执行时机 #400

Open
shuqingzai opened this issue Nov 25, 2024 · 3 comments
Open

前置请求中间件执行时机 #400

shuqingzai opened this issue Nov 25, 2024 · 3 comments

Comments

@shuqingzai
Copy link

目前用户自定义的前置中间件执行时机在系统前置中间件之前,会导致在前置中间件中无法获取实际请求的参数,如 一些 API 需要使用参数做签名,目前只能通过 Client 中间件,但是项目中 Client 的链路追踪中间件会被设置最上层,其他 Client 会基于一个基础 Client Clone 出来,导致如果在新增的 Client 中间件中追加请求参数(如:签名 header 、 params 等),链路追踪中间件无法收集这些参数,除非是在响应时又覆盖请求参数,这样的做法不太好,是否可以提供一种方式方式,在解析请求参数之后, Client 中间件执行之前修改请求参数呢?

req/request.go

Lines 654 to 669 in 24b0c84

for _, f := range r.client.udBeforeRequest {
if err = f(r.client, r); err != nil {
return
}
}
for _, f := range r.client.beforeRequest {
if err = f(r.client, r); err != nil {
return
}
}
if r.client.wrappedRoundTrip != nil {
resp, err = r.client.wrappedRoundTrip.RoundTrip(r)
} else {
resp, err = r.client.roundTrip(r)
}

@shuqingzai
Copy link
Author

@imroc 是否可以提供一种新的中间件在 r.client.beforeRequest 之后运行?

@imroc
Copy link
Owner

imroc commented Dec 2, 2024

一般路追踪中间件就用 client 中间件,是在 beforeRequest 之后运行的。你说的 如果在新增的 Client 中间件中追加请求参数(如:签名 header 、 params 等),链路追踪中间件无法收集这些参数 没太理解,能否举个实际的例子

@shuqingzai
Copy link
Author

一般路追踪中间件就用 client 中间件,是在 beforeRequest 之后运行的。你说的 如果在新增的 Client 中间件中追加请求参数(如:签名 header 、 params 等),链路追踪中间件无法收集这些参数 没太理解,能否举个实际的例子

@imroc 简单的代码流程

package main

import (
	"github.com/imroc/req/v3"
)

// _client 项目全局 HTTP 客户端
var  _client = req.C()
func init() {
	_client.WrapRoundTripFunc(func(rt req.RoundTripper) req.RoundTripFunc {
		return func(req *req.Request) (resp *req.Response, err error) {
			// 用于记录 tracing or metrics
			// 记录请求信息

			// before request
			// ...
			resp, err = rt.RoundTrip(req)
			// 记录响应信息

			// after response
			// ...
			return
		}
	})
}

// githubClient
func githubClient() *req.Client {
	c := _client.Clone()
	// 签名
	c.WrapRoundTripFunc(func(rt req.RoundTripper) req.RoundTripFunc {
		return func(req *req.Request) (resp *req.Response, err error) {
			// 签名逻辑
			req.SetHeader("X-signature", "...")
			// 由于该中间件是在 tracing/metrics 中间件之后,所以无法记录签名信息

			// ...
			resp, err = rt.RoundTrip(req)
			return
		}
	})
	return c
}

func main() {
	
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants