-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathroutes.go
145 lines (113 loc) · 3.31 KB
/
routes.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
142
143
144
145
package there
import (
path2 "path"
"strings"
)
type RouteGroup struct {
*Router
prefix string
}
func (group RouteGroup) Group(prefix string) *RouteGroup {
prefix = strings.TrimPrefix(prefix, "/")
group.assert(len(prefix) > 1, "route group needs to have at least one symbol")
if !strings.HasSuffix(prefix, "/") {
prefix += "/"
}
group.prefix += prefix
return &group
}
func NewRouteGroup(router *Router, route string) *RouteGroup {
router.assert(route != "", "route \""+route+"\" must not be empty")
if !strings.HasPrefix(route, "/") {
route = "/" + route
}
if !strings.HasSuffix(route, "/") {
route += "/"
}
return &RouteGroup{
Router: router,
prefix: route,
}
}
type Endpoint func(request Request) Response
// Route adds attributes to an Endpoint func
type Route struct {
muxHandler *muxHandler
methods []method
}
func (group *RouteGroup) Handle(path string, endpoint Endpoint, methodsString ...string) *RouteRouteGroupBuilder {
group.Router.mutex.Lock()
defer group.Router.mutex.Unlock()
var methods []method
for _, m := range methodsString {
methods = append(methods, methodToInt(m))
}
if path == "" {
path = "/"
}
if path[0] == '/' {
path = "/" + path
}
path = group.prefix + path
path = path2.Clean(path)
var ok bool
var muxHandler *muxHandler
muxHandler, ok = group.Router.handlerKeeper[path]
if !ok {
muxHandler = newMuxHandler(group.Router, endpoint)
group.serveMux.Handle(path, muxHandler)
group.Router.handlerKeeper[path] = muxHandler
}
for _, m := range methods {
muxHandler.methods[m] = &muxHandlerEndpoint{
endpoint: endpoint,
}
}
route := &Route{
muxHandler,
methods,
}
return &RouteRouteGroupBuilder{
route,
group,
}
}
type RouteRouteGroupBuilder struct {
*Route
*RouteGroup
}
func (group *RouteGroup) Get(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodGet)
}
func (group *RouteGroup) Post(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodPost)
}
func (group *RouteGroup) Patch(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodPatch)
}
func (group *RouteGroup) Delete(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodDelete)
}
func (group *RouteGroup) Connect(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodConnect)
}
func (group *RouteGroup) Head(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodHead)
}
func (group *RouteGroup) Trace(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodTrace)
}
func (group *RouteGroup) Put(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodPut)
}
func (group *RouteGroup) Options(route string, endpoint Endpoint) *RouteRouteGroupBuilder {
return group.Handle(route, endpoint, MethodOptions)
}
// With adds a middleware to the handler the method is called on
func (group *RouteRouteGroupBuilder) With(middleware Middleware) *RouteRouteGroupBuilder {
for _, method := range group.methods {
endpoint := group.muxHandler.methods[method]
endpoint.AddMiddleware(middleware)
}
return group
}