-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgroup.go
141 lines (124 loc) · 3.69 KB
/
group.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package min
import (
"net/http"
"path"
)
// Group represents a route group that shares a middleware chain and a common
// path.
type Group struct {
Path string
handler Handler
parent *Group
entryChain Middleware
exitChain Middleware
}
// NewGroup creates a new subgroup of group g.
func (g *Group) NewGroup(path string) *Group {
return &Group{
Path: path,
handler: g.handler,
parent: g,
}
}
// Parent gets the group's parent in the group tree.
func (g *Group) Parent() *Group {
return g.parent
}
// FullPath returns the group's full path in the group tree (as opposed to this
// group's sub-path)
func (g *Group) FullPath() string {
if g.parent == nil {
return g.Path
}
return path.Join(g.parent.FullPath(), g.Path)
}
// Use sets this group's middleware chain. Each call to Use appends to the
// chain. Calls Entry in v1.1.0
func (g *Group) Use(m Middleware) {
g.Entry(m)
}
// Entry sets this group's entry middleware chain. Entry middleware is executed
// from the start of the request and hands off to the handler at the end.
//
// The ResponseWriter and Request passed along the chain are shared, which means
// that their read & write state is preserved and the usual semantics apply.
//
// Each call to Entry appends to the entry chain.
func (g *Group) Entry(m Middleware) {
if g.entryChain == nil {
g.entryChain = m
return
}
g.entryChain = g.entryChain.Then(m)
}
// Exit sets this group's exit middleware chain. Exit middleware is executed
// from after the handler has returned onwards.
//
// The ResponseWriter and Request passed along the chain are shared, which means
// that their read & write state is preserved and the usual semantics apply.
//
// Each call to Exit appends to the exit chain.
func (g *Group) Exit(m Middleware) {
if g.exitChain == nil {
g.exitChain = m
return
}
g.exitChain = g.exitChain.Then(m)
}
func (g *Group) handle(method, relativePath string, handler http.Handler) {
entryChain := g.fullEntryChain()
if entryChain != nil {
handler = entryChain(handler)
}
exitChain := g.fullExitChain()
if exitChain != nil {
handler = connect(handler, exitChain)
}
g.handler.Handle(method, path.Join(g.FullPath(), relativePath), handler)
}
func (g *Group) fullEntryChain() Middleware {
if g.parent == nil && g.entryChain == nil {
return nil
}
if g.parent == nil {
return g.entryChain
}
parentChain := g.parent.fullEntryChain()
if parentChain == nil {
return g.entryChain
}
return parentChain.Then(g.entryChain)
}
func (g *Group) fullExitChain() Middleware {
if g.parent == nil && g.exitChain == nil {
return nil
}
if g.parent == nil {
return g.exitChain
}
parentChain := g.parent.fullExitChain()
if g.exitChain == nil {
return parentChain
}
return g.exitChain.Then(parentChain)
}
// Get registers a handler for GET requests on the given relative path.
func (g *Group) Get(relativePath string, handler http.Handler) {
g.handle(http.MethodGet, relativePath, handler)
}
// Post registers a handler for POST requests on the given relative path.
func (g *Group) Post(relativePath string, handler http.Handler) {
g.handle(http.MethodPost, relativePath, handler)
}
// Put registers a handler for PUT requests on the given relative path.
func (g *Group) Put(relativePath string, handler http.Handler) {
g.handle(http.MethodPut, relativePath, handler)
}
// Patch registers a handler for PATCH requests on the given relative path.
func (g *Group) Patch(relativePath string, handler http.Handler) {
g.handle(http.MethodPatch, relativePath, handler)
}
// Delete registers a handler for DELETE requests on the given relative path.
func (g *Group) Delete(relativePath string, handler http.Handler) {
g.handle(http.MethodDelete, relativePath, handler)
}