原文地址:https://cch123.github.io/httprouter/
http router是什么
功能上讲就是url->hander函数
http router构造
- 单节点代表一个字母
- 需要对字符串匹配只要从根节点依次匹配
- 缺点:1.树深度和路由字符串长度正相关,2.占用较多内存,3.字符串越长,匹配越慢(类似链表结构,在内存中存储不连续数据)
restful风格路由
同一个url会提供多个http方法,对资源进行创建更新删除获取
get put post 等各一颗
httprouter一些概念
- node就是httprouter树中节点
- ntype 就是node type 有几种枚举,1.static 非根节点普通字符串节点,2.root 根节点,3.param 参数节点(:id),4.catchall 通配符节点(*all)
path
到达根节点,所经过的字符串路径
indices
子节点索引,当子节点是是非参数类型,即本节点wildchild是false时,会将每个子节点首字母放在该索引组,实际是string
如果子节点是参数节点,indices应该是空字符串
wildchild
如果一个节点字节点中有param(wildchild)节点,那该节点wildchild就是true
catchall
以*结尾路由,catchall在静态文件用的多
httprouter 中dadix tree的构造
假定插入三条路由,都用get
第一条路由
/marketplace_listing/plans/
第二条路由
/marketplace_listing/plans/:id/acounts
第三条路由
路由冲突
路由发生冲突,主要是static节点,param节点,catchall节点
例如
conflict:
GET /user/info/:name
GET /user/:id
param节点和普通字符串节点无法共存,上述info会被解释为:id
如果是method不同即可
所有情况
- 在插入 wildcard 节点时,父节点的 children 数组非空且 wildChild 被设置为 false。例如:GET /user/getAll 和 GET /user/:id/getAddr,或者 GET /user/*aaa和 GET /user/:id。
- 在插入 wildcard 节点时,父节点的 children 数组非空且 wildChild 被设置为 true,但该父节点的 wildcard 子节点要插入的 wildcard 名字不一样。例如: GET /user/:id/info 和 GET /user/:name/info。
- 在插入 catchAll 节点时,父节点的 children 非空。例如: GET /src/abc 和 GET /src/filename,或者 GET /src/:id 和 GET /src/filename。
- 在插入 static 节点时,父节点的 wildChild 字段被设置为 true。
- 在插入 static 节点时,父节点的 children 非空,且子节点 nType 为 catchAll。
以上均为错误冲突情况
正确应该是
即同一个节点,其子节点的情况只可能是:
- 一个 wildcard 节点
- 一个 catchAll 节点
- 一个或多个 static 节点