req icon indicating copy to clipboard operation
req copied to clipboard

前置请求中间件执行时机

Open shuqingzai opened this issue 1 year ago • 3 comments

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

https://github.com/imroc/req/blob/24b0c84d2d4dac890b39f1d9a9ca494ac2f9a6d5/request.go#L654-L669

shuqingzai avatar Nov 25 '24 02:11 shuqingzai

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

shuqingzai avatar Nov 25 '24 02:11 shuqingzai

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

imroc avatar Dec 02 '24 02:12 imroc

一般路追踪中间件就用 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() {
	
}

shuqingzai avatar Dec 02 '24 03:12 shuqingzai