Skip to content

Commit 3cba71a

Browse files
committed
handle route parameters, fix empty handler bug
1 parent dca5855 commit 3cba71a

File tree

1 file changed

+68
-32
lines changed

1 file changed

+68
-32
lines changed

router.go

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,55 @@ package routing
22

33
import (
44
"github.com/valyala/fasthttp"
5+
"strings"
56
)
67

78
type Handler func(ctx *Context) error
89

9-
type Router struct {
10-
routes map[string]*route
11-
stores map[string]RouteStore
12-
notFoundHandler Handler
13-
maxParams int
10+
type Route struct {
11+
Path string
12+
ParamNames []string
13+
Handlers []Handler
1414
}
1515

16-
func CombineHandlers(handlers ...Handler) Handler {
17-
return func(ctx *Context) error {
18-
for _, handler := range handlers {
19-
if err := handler(ctx); err != nil {
20-
return err
21-
}
22-
}
23-
return nil
24-
}
16+
type Router struct {
17+
routes map[string][]*Route
18+
notFoundHandler Handler
2519
}
2620

2721
func New() *Router {
2822
return &Router{
29-
routes: make(map[string]*route),
30-
stores: make(map[string]RouteStore),
23+
routes: make(map[string][]*Route),
3124
}
3225
}
3326

3427
func (r *Router) add(method, path string, handlers []Handler) {
35-
s := r.stores[method]
36-
if s == nil {
37-
s = newStore()
38-
r.stores[method] = s
28+
route := &Route{
29+
Path: path,
30+
Handlers: handlers,
3931
}
40-
if n := s.Add(path, handlers); n > r.maxParams {
41-
r.maxParams = n
32+
33+
parts := strings.Split(path, "/")
34+
for _, part := range parts {
35+
if strings.HasPrefix(part, ":") {
36+
route.ParamNames = append(route.ParamNames, strings.TrimPrefix(part, ":"))
37+
}
4238
}
43-
r.routes[method+path] = &route{method, path, CombineHandlers(handlers...)}
39+
route.Path = strings.Join(parts, "/")
40+
41+
r.routes[method] = append(r.routes[method], route)
4442
}
4543

4644
func (r *Router) find(method, path string) []Handler {
47-
s := r.stores[method]
48-
if s == nil {
49-
return []Handler{}
50-
}
51-
handlers, ok := s.Get(path).([]Handler)
52-
if !ok {
53-
return []Handler{}
45+
routes := r.routes[method]
46+
for _, route := range routes {
47+
if matches, params := route.match(path); matches {
48+
c := NewContext(nil, nil)
49+
c.params = params
50+
return route.Handlers
51+
}
5452
}
55-
return handlers
53+
return nil
5654
}
5755

5856
func RouterHandler(router *Router) func(ctx *fasthttp.RequestCtx) {
@@ -64,7 +62,24 @@ func RouterHandler(router *Router) func(ctx *fasthttp.RequestCtx) {
6462
ctx.Error("Not found", fasthttp.StatusNotFound)
6563
return
6664
}
67-
c := NewContext(ctx)
65+
66+
params := make(map[string]string)
67+
for _, route := range router.routes[method] {
68+
if matches, params := route.match(path); matches {
69+
c := NewContext(ctx, nil).WithParams(params)
70+
for _, h := range handlers {
71+
err := h(c)
72+
if err != nil {
73+
ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
74+
return
75+
}
76+
}
77+
return
78+
}
79+
}
80+
81+
c := NewContext(ctx, params)
82+
6883
for _, h := range handlers {
6984
err := h(c)
7085
if err != nil {
@@ -74,3 +89,24 @@ func RouterHandler(router *Router) func(ctx *fasthttp.RequestCtx) {
7489
}
7590
}
7691
}
92+
93+
func (r *Route) match(path string) (bool, map[string]string) {
94+
parts := strings.Split(path, "/")
95+
routeParts := strings.Split(r.Path, "/")
96+
97+
if len(parts) != len(routeParts) {
98+
return false, nil
99+
}
100+
101+
params := make(map[string]string)
102+
for i, part := range routeParts {
103+
if strings.HasPrefix(part, ":") {
104+
paramName := strings.TrimPrefix(part, ":")
105+
params[paramName] = parts[i]
106+
} else if part != parts[i] {
107+
return false, nil
108+
}
109+
}
110+
111+
return true, params
112+
}

0 commit comments

Comments
 (0)