递归插入和搜索实现服务框架
【摘要】 1 简介本文代码模板是一个最小型 Web 框架,包含: Radix 树路由匹配 Context 封装请求响应 中间件机制 JSON 响应运行方式:保存代码到 webwork.go执行 go run webwork.go访问 http://localhost:8080/ping 2 代码和解释这个示例中实现了类似 Radix 树 (基数树) 的路由管理,但还不算完全的...
1 简介
本文代码模板是一个最小型 Web 框架,包含:
Radix 树路由匹配
Context 封装请求响应
中间件机制
JSON 响应
运行方式:
保存代码到 webwork.go
执行 go run webwork.go
2 代码和解释
这个示例中实现了类似 Radix 树 (基数树) 的路由管理,但还不算完全的 Radix 树实现,原因在于:
✅ 体现 Radix 树特性的部分:
公共前缀匹配:代码中通过 strings.HasPrefix() 判断路径的公共前缀。
子节点管理:每个节点存储 children map[string]*RadixNode,表示多叉节点。
递归插入和搜索:路径被分段进行匹配,符合 Radix 树逐层深入匹配的思路。
❌ 不完整的地方:
路径压缩:真实的 Radix 树应该将公共前缀直接合并到节点路径中,而不是像这里直接存完整路径。
动态路由参数:没有实现 /user/:id 这种通配符匹配。
回溯优化:没有实现路径回退或者模糊匹配。
如果希望将这个代码完善为完整的 Radix 树路由匹配器,可以按照以下步骤改造:
节点路径保存公共前缀 (prefix)
动态路由参数匹配 (:id 或 *wildcard)
路径压缩(合并公共前缀)
支持模糊匹配和可选路径
自定义中间件处理链
-
完整代码
// Context 封装请求和响应 type Context struct { Writer http.ResponseWriter Request *http.Request Params map[string]string index int handlers []HandlerFunc } type HandlerFunc func(*Context) func (c *Context) JSON(status int, data string) { c.Writer.Header().Set("Content-Type", "application/json") c.Writer.WriteHeader(status) c.Writer.Write([]byte(data)) } func (c *Context) Next() { c.index++ for c.index < len(c.handlers) { c.handlers[c.index](c) c.index++ } } // 路由节点 type RadixNode struct { path string handler HandlerFunc children map[string]*RadixNode } func NewRadixNode() *RadixNode { return &RadixNode{children: make(map[string]*RadixNode)} } func (n *RadixNode) Insert(path string, handler HandlerFunc) { if path == "" { n.handler = handler return } for prefix, child := range n.children { if strings.HasPrefix(path, prefix) { child.Insert(path[len(prefix):], handler) return } } n.children[path] = &RadixNode{path: path, handler: handler, children: make(map[string]*RadixNode)} } func (n *RadixNode) Search(path string) HandlerFunc { if path == "" && n.handler != nil { return n.handler } for prefix, child := range n.children { if strings.HasPrefix(path, prefix) { return child.Search(path[len(prefix):]) } } return nil } // Web框架引擎 type Engine struct { route *RadixNode } func NewEngine() *Engine { return &Engine{route: NewRadixNode()} } func (e *Engine) GET(path string, handler HandlerFunc) { e.route.Insert(path, handler) } func (e *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { handler := e.route.Search(req.URL.Path) if handler != nil { c := &Context{Writer: w, Request: req, handlers: []HandlerFunc{handler}} c.Next() } else { http.NotFound(w, req) } } func main() { r := NewEngine() r.GET("/ping", func(c *Context) { c.JSON(200, `{"message": "pong"}`) }) http.ListenAndServe(":8080", r) fmt.Println("Server is running at :8080") }
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)