From 0786a97a770c91bf9f7bdcce07046aac6368a607 Mon Sep 17 00:00:00 2001 From: Muyao CHEN Date: Thu, 26 Sep 2024 19:01:34 +0200 Subject: [PATCH] context: Get params from url --- framework/context.go | 6 +++++- framework/core.go | 17 ++++++++++------- framework/trie.go | 30 +++++++++++++++++++++++++++--- handlers.go | 1 + routes.go | 1 + 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/framework/context.go b/framework/context.go index 8bd882b..81a96df 100644 --- a/framework/context.go +++ b/framework/context.go @@ -19,7 +19,7 @@ type Context struct { // current handler index index int - params map[string]any + params map[string]string hasTimeout bool writerMux *sync.Mutex @@ -117,4 +117,8 @@ func (ctx *Context) SetHandlers(handlers []ControllerHandler) { ctx.handlers = handlers } +func (ctx *Context) SetParams(params map[string]string) { + ctx.params = params +} + // }}} diff --git a/framework/core.go b/framework/core.go index 3f3d827..a657f1d 100644 --- a/framework/core.go +++ b/framework/core.go @@ -66,7 +66,7 @@ func (c *Core) Use(middlewares ...ControllerHandler) { } // FindRouteByRequest finds route using the request -func (c *Core) FindRouteByRequest(r *http.Request) []ControllerHandler { +func (c *Core) FindRouteByRequest(r *http.Request) *node { upperMethod := strings.ToUpper(r.Method) mapper, ok := c.router[upperMethod] @@ -75,13 +75,13 @@ func (c *Core) FindRouteByRequest(r *http.Request) []ControllerHandler { return nil } - controllers := mapper.FindRoute(r.URL.Path) - if controllers == nil { + node := mapper.FindRoute(r.URL.Path) + if node == nil { log.Printf("URI %q is not recognized\n", r.URL.Path) return nil } - return controllers + return node } func (c *Core) Group(prefix string) IGroup { @@ -97,13 +97,16 @@ func (c *Core) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := NewContext(w, r) - handlers := c.FindRouteByRequest(r) - if handlers == nil { + node := c.FindRouteByRequest(r) + if node == nil { ctx.WriteJSON(http.StatusNotFound, "Request not found") return } - ctx.SetHandlers(handlers) + params := node.ParseParamsFromEndNode(r.URL.Path) + + ctx.SetParams(params) + ctx.SetHandlers(node.handlers) if err := ctx.Next(); err != nil { ctx.WriteJSON(http.StatusInternalServerError, "Internal error") diff --git a/framework/trie.go b/framework/trie.go index aad7924..83e1673 100644 --- a/framework/trie.go +++ b/framework/trie.go @@ -14,11 +14,11 @@ func NewTrie() *Trie { return &Trie{root: newNode("")} } -func (t *Trie) FindRoute(uri string) []ControllerHandler { +func (t *Trie) FindRoute(uri string) *node { uri = strings.ToUpper(uri) uri = strings.TrimPrefix(uri, "/") if uri == "" { - return t.root.handlers + return t.root } found := t.root.findRoute(uri) @@ -26,7 +26,7 @@ func (t *Trie) FindRoute(uri string) []ControllerHandler { return nil } - return found.handlers + return found } func (t *Trie) AddRouter(uri string, handlers []ControllerHandler) error { @@ -58,6 +58,29 @@ type node struct { segment string handlers []ControllerHandler children []*node + parent *node +} + +func (n *node) ParseParamsFromEndNode(uri string) map[string]string { + ret := map[string]string{} + uri = strings.ToUpper(uri) + uri = strings.TrimPrefix(uri, "/") + if uri == "" { + // root + return ret + } + segments := strings.Split(uri, "/") + cnt := len(segments) + cur := n + + for i := cnt - 1; i >= 0; i-- { + if isWildcard(cur.segment) { + // set params + ret[cur.segment[1:]] = segments[i] + } + cur = cur.parent + } + return ret } func newNode(segment string) *node { @@ -138,6 +161,7 @@ func (n *node) addRoute(uri string, handlers []ControllerHandler) error { // create a new node new := newNode(splitted[0]) + new.parent = n if isLast { // this is the end new.handlers = append(new.handlers, handlers...) diff --git a/handlers.go b/handlers.go index d5bbc9c..cd03123 100644 --- a/handlers.go +++ b/handlers.go @@ -74,6 +74,7 @@ func SubjectUpdateController(ctx *framework.Context) error { func SubjectGetController(ctx *framework.Context) error { ctx.WriteJSON(http.StatusAccepted, "got") + log.Println(ctx.ParamInt("ID", 0)) return nil } diff --git a/routes.go b/routes.go index 106fcc1..aab7cb7 100644 --- a/routes.go +++ b/routes.go @@ -15,6 +15,7 @@ func registerRouter(core *framework.Core) { subjectApi.Delete("/:id", SubjectDelController) subjectApi.Put("/:id", SubjectUpdateController) subjectApi.Get("/:id", SubjectGetController) + subjectApi.Get("/:id/test", SubjectGetController) subjectApi.Get("/list/all", SubjectListController) } }