Skip to content

Commit 1b632f6

Browse files
committed
refactor: 调整中间件的调用顺序
1 parent 2f4db8b commit 1b632f6

File tree

5 files changed

+34
-42
lines changed

5 files changed

+34
-42
lines changed

internal/tree/method.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (n *node[T]) addMethods(h T, pattern string, ms []types.MiddlewareOf[T], me
110110
}
111111

112112
if _, found := n.handlers[methodNotAllowed]; !found {
113-
n.handlers[methodNotAllowed] = n.root.methodNotAllowedBuilder(n)
113+
n.handlers[methodNotAllowed] = ApplyMiddleware(n.root.methodNotAllowedBuilder(n), "", pattern, ms...)
114114
}
115115

116116
n.buildMethods()

internal/tree/tree.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func New[T any](lock bool, i *syntax.Interceptors, notFound T, trace bool, metho
8282
// Add 添加路由项
8383
//
8484
// methods 可以为空,表示添所有支持的请求方法,其中的 HEAD 和 OPTIONS 不受控。
85-
func (tree *Tree[T]) Add(pattern string, h T, middlewares []types.MiddlewareOf[T], methods ...string) error {
85+
func (tree *Tree[T]) Add(pattern string, h T, ms []types.MiddlewareOf[T], methods ...string) error {
8686
if err := tree.checkAmbiguous(pattern); err != nil {
8787
return err
8888
}
@@ -104,7 +104,7 @@ func (tree *Tree[T]) Add(pattern string, h T, middlewares []types.MiddlewareOf[T
104104
if len(methods) == 0 {
105105
methods = addAny
106106
}
107-
return n.addMethods(h, pattern, middlewares, methods...)
107+
return n.addMethods(h, pattern, ms, methods...)
108108
}
109109

110110
func (tree *Tree[T]) checkAmbiguous(pattern string) error {

router.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ func (r *RouterOf[T]) Routes() map[string][]string { return r.tree.Routes() }
102102
func (r *RouterOf[T]) Remove(pattern string, methods ...string) { r.tree.Remove(pattern, methods...) }
103103

104104
// Use 使用中间件
105+
//
106+
// 对于中间件的使用,除了此方法,还可以 [RouterOf.Prefix]、[RouterOf.Resource]、[PrefixOf.Prefix]
107+
// 以及添加路由项时指定。调用顺序如下:
108+
// - Get/Delete 等添加路由项的方法;
109+
// - [RouterOf.Prefix]、[RouterOf.Resource]、[PrefixOf.Prefix];
110+
// - [Router.Use];
105111
func (r *RouterOf[T]) Use(m ...types.MiddlewareOf[T]) {
106112
r.middleware = append(r.middleware, m...)
107113
r.tree.ApplyMiddleware(m...)
@@ -112,7 +118,7 @@ func (r *RouterOf[T]) Use(m ...types.MiddlewareOf[T]) {
112118
// pattern 为路由匹配模式,可以是正则匹配也可以是字符串匹配,
113119
// 若语法不正确,则直接 panic,可以通过 [CheckSyntax] 检测语法的有效性,其它接口也相同;
114120
// m 为应用于当前路由项的中间件;
115-
// methods 该路由项对应的请求方法,如果未指定值,则表示所有支持的请求方法,其中 OPTIONS 和 HEAD 不受控;
121+
// methods 该路由项对应的请求方法,如果未指定值,则表示所有支持的请求方法,其中 OPTIONS、TRACE 和 HEAD 不受控;
116122
func (r *RouterOf[T]) Handle(pattern string, h T, m []types.MiddlewareOf[T], methods ...string) *RouterOf[T] {
117123
m = slices.Concat(m, r.middleware)
118124
if err := r.tree.Add(pattern, h, m, methods...); err != nil {
@@ -273,7 +279,7 @@ func (p *PrefixOf[T]) URL(strict bool, pattern string, params map[string]string)
273279
//
274280
// m 中间件函数,按顺序调用,会继承 p 的中间件并按在 m 之前;
275281
func (p *PrefixOf[T]) Prefix(prefix string, m ...types.MiddlewareOf[T]) *PrefixOf[T] {
276-
return p.router.Prefix(p.Pattern()+prefix, slices.Concat(p.middleware, m)...)
282+
return p.router.Prefix(p.Pattern()+prefix, slices.Concat(m, p.middleware)...)
277283
}
278284

279285
// Prefix 声明一个 [PrefixOf] 实例
@@ -351,7 +357,7 @@ func (r *RouterOf[T]) Resource(pattern string, m ...types.MiddlewareOf[T]) *Reso
351357
// pattern 资源地址;
352358
// m 中间件函数,按顺序调用,会继承 p 的中间件并按在 m 之前;
353359
func (p *PrefixOf[T]) Resource(pattern string, m ...types.MiddlewareOf[T]) *ResourceOf[T] {
354-
return p.router.Resource(p.Pattern()+pattern, slices.Concat(p.middleware, m)...)
360+
return p.router.Resource(p.Pattern()+pattern, slices.Concat(m, p.middleware)...)
355361
}
356362

357363
// Router 返回与当前资源关联的 [RouterOf] 实例

router_test.go

+19-35
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,14 @@ func TestRouterOf_Middleware(t *testing.T) {
189189
def := std.NewRouter("")
190190
a.NotNil(def)
191191
def.Use(tree.BuildTestMiddleware(a, "m1"), tree.BuildTestMiddleware(a, "m2"), tree.BuildTestMiddleware(a, "m3"), tree.BuildTestMiddleware(a, "m4"))
192-
def.Get("/get", rest.BuildHandler(a, 201, "", nil))
192+
def.Get("/get", rest.BuildHandler(a, 201, "", nil), tree.BuildTestMiddleware(a, "m0"))
193193
def.Post("/get", rest.BuildHandler(a, 201, "", nil))
194194

195-
rest.Get(a, "/get").Do(def).Status(201).StringBody("m1m2m3m4")
196-
rest.Post(a, "/get", nil).Do(def).Status(201).StringBody("m1m2m3m4")
197-
rest.Get(a, "/get").Do(def).Status(201).StringBody("m1m2m3m4")
195+
rest.Get(a, "/get").Do(def).Status(201).StringBody("m0m1m2m3m4")
198196
rest.Post(a, "/get", nil).Do(def).Status(201).StringBody("m1m2m3m4")
199197

200198
def.Use(tree.BuildTestMiddleware(a, "m5"), tree.BuildTestMiddleware(a, "m6"))
201-
rest.Get(a, "/get").Do(def).Status(201).StringBody("m1m2m3m4m5m6")
199+
rest.Get(a, "/get").Do(def).Status(201).StringBody("m0m1m2m3m4m5m6")
202200
}
203201

204202
func TestResourceOf(t *testing.T) {
@@ -247,17 +245,18 @@ func TestRouterOf_Resource(t *testing.T) {
247245
a := assert.New(t, false)
248246
def := std.NewRouter("")
249247
a.NotNil(def)
248+
def.Use(tree.BuildTestMiddleware(a, "d1"))
250249

251-
r1 := def.Resource("/abc/1")
250+
r1 := def.Resource("/abc/1", tree.BuildTestMiddleware(a, "r1"))
252251
a.NotNil(r1)
253252
a.Equal(r1.Router(), def)
254253

255-
r2 := def.Resource("/abc/1")
254+
r2 := def.Resource("/abc/1", tree.BuildTestMiddleware(a, "r1"))
256255
a.NotNil(r2)
257256
a.False(r1 == r2) // 不是同一个 *Resource
258257

259-
r2.Delete(rest.BuildHandler(a, 201, "", nil))
260-
rest.Delete(a, "/abc/1").Do(def).Status(201)
258+
r2.Delete(rest.BuildHandler(a, 201, "-201-", nil), tree.BuildTestMiddleware(a, "d1"))
259+
rest.Delete(a, "/abc/1").Do(def).Status(201).StringBody("-201-d1r1d1")
261260
}
262261

263262
func TestPrefix_Resource(t *testing.T) {
@@ -272,9 +271,9 @@ func TestPrefix_Resource(t *testing.T) {
272271
r1 := p.Resource("/abc/1", tree.BuildTestMiddleware(a, "r1"), tree.BuildTestMiddleware(a, "r2"))
273272
a.NotNil(r1)
274273

275-
r1.Delete(rest.BuildHandler(a, 201, "-201-", nil))
276-
rest.Delete(a, "/p1/abc/1").Do(def).Status(201).StringBody("-201-p1p2r1r2")
277-
rest.Delete(a, "/p1/abc/1").Do(def).Status(201).StringBody("-201-p1p2r1r2")
274+
r1.Delete(rest.BuildHandler(a, 201, "-201-", nil), tree.BuildTestMiddleware(a, "m1"))
275+
rest.Delete(a, "/p1/abc/1").Do(def).Status(201).StringBody("-201-m1r1r2p1p2")
276+
rest.Delete(a, "/p1/abc/1").Do(def).Status(201).StringBody("-201-m1r1r2p1p2")
278277
}
279278

280279
func TestResourceOf_URL(t *testing.T) {
@@ -374,7 +373,7 @@ func TestPrefixOf(t *testing.T) {
374373
rest.NewRequest(a, http.MethodOptions, "/p/h/any").Do(r).Status(404)
375374
}
376375

377-
func TestRouterOf_Prefix(t *testing.T) {
376+
func TestPrefixOf_Prefix(t *testing.T) {
378377
t.Run("prefix", func(t *testing.T) {
379378
a := assert.New(t, false)
380379
def := std.NewRouter("", mux.AllowedCORS(3600))
@@ -384,7 +383,7 @@ func TestRouterOf_Prefix(t *testing.T) {
384383
a.Equal(p.Router(), def)
385384
})
386385

387-
t.Run("prefix with middleware", func(t *testing.T) {
386+
t.Run("empty prefix", func(t *testing.T) {
388387
a := assert.New(t, false)
389388
def := std.NewRouter("", mux.AllowedCORS(3600))
390389
a.NotNil(def)
@@ -397,42 +396,27 @@ func TestRouterOf_Prefix(t *testing.T) {
397396
rest.Delete(a, "/abc").Do(def).Status(201)
398397
})
399398

400-
t.Run("empty prefix with middleware", func(t *testing.T) {
399+
//
400+
t.Run("prefix 的中间调用顺序", func(t *testing.T) {
401401
a := assert.New(t, false)
402402
def := std.NewRouter("", mux.AllowedCORS(3600))
403403
a.NotNil(def)
404+
def.Use(tree.BuildTestMiddleware(a, "r0"))
404405

405-
p := def.Prefix("/abc")
406+
p := def.Prefix("/abc", tree.BuildTestMiddleware(a, "p1"))
406407
a.Equal(p.Router(), def)
407408

408-
pp := p.Prefix("", tree.BuildTestMiddleware(a, "p1"), tree.BuildTestMiddleware(a, "p2"))
409+
pp := p.Prefix("", tree.BuildTestMiddleware(a, "p2"), tree.BuildTestMiddleware(a, "p3"))
409410
pp.Delete("", rest.BuildHandler(a, 201, "-201-", nil))
410411

411-
rest.Delete(a, "/abc").Do(def).Status(201).StringBody("-201-p1p2")
412+
rest.Delete(a, "/abc").Do(def).Status(201).StringBody("-201-p2p3p1r0")
412413

413414
// Trace
414415
rest.NewRequest(a, http.MethodTrace, "/abc").Do(def).Status(http.StatusMethodNotAllowed)
415416
rest.NewRequest(a, http.MethodTrace, "/abc/not-exists").Do(def).Status(http.StatusNotFound)
416417
})
417418
}
418419

419-
func TestPrefixOf_Prefix(t *testing.T) {
420-
a := assert.New(t, false)
421-
def := std.NewRouter("", mux.AllowedCORS(3600), mux.Trace(true))
422-
a.NotNil(def)
423-
424-
p := def.Prefix("/abc", tree.BuildTestMiddleware(a, "p1"), tree.BuildTestMiddleware(a, "p2"))
425-
pp := p.Prefix("/def", tree.BuildTestMiddleware(a, "pp1"), tree.BuildTestMiddleware(a, "pp2"))
426-
a.Equal(p.Router(), def)
427-
pp.Delete("", rest.BuildHandler(a, 201, "-201-", nil))
428-
429-
rest.Delete(a, "/abc/def").Do(def).Status(201).StringBody("-201-p1p2pp1pp2")
430-
431-
// Trace
432-
rest.NewRequest(a, http.MethodTrace, "/abc/def").Do(def).Status(http.StatusOK)
433-
rest.NewRequest(a, http.MethodTrace, "/abc/not-exists").Do(def).Status(http.StatusOK)
434-
}
435-
436420
func TestPrefixOf_URL(t *testing.T) {
437421
a := assert.New(t, false)
438422
def := std.NewRouter("", mux.AllowedCORS(3600), mux.URLDomain("https://example.com"))

types/types.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ type MiddlewareOf[T any] interface {
117117
// method 当前路由的请求方法;
118118
// pattern 当前路由的匹配项;
119119
//
120-
// 对于不存在的路由项,method 和 pattern 都为空。
120+
// NOTE: method 和 pattern 在某些特殊的路由项中会有特殊的值:
121+
// - 404 method 和 pattern 均为空;
122+
// - 405 method 为空,pattern 正常;
121123
Middleware(next T, method, pattern string) T
122124
}
123125

0 commit comments

Comments
 (0)