02.Mygin实现简单的路由
本文是Mygin第二篇
目的:
- 实现路由映射
- 提供了用户注册静态路由方法(GET、POST方法)
基于上一篇 Mygin 实现简单Http 且参照Gin
- 使用了map数组实现简单路由的映射关系
- 不同的method对应一个组,Gin框架初始化时map时初始化9个,因为支持的http.method刚好为9个
1 | package http |
mygin路由功能实现
- mygin/engine.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
79package mygin
import (
"log"
"net/http"
)
type Engine struct {
trees methodTrees
}
// 路由树
type methodTrees map[string]methodTree
// 路由节点
type methodTree struct {
method string
paths map[string]http.HandlerFunc
}
// 获取路由root根
func (e *Engine) getRoot(method string) methodTree {
if root, ok := e.trees[method]; ok {
return root
}
e.trees[method] = methodTree{method: method, paths: make(map[string]http.HandlerFunc)}
return e.trees[method]
}
// 添加路由方法
func (e *Engine) addRoute(method, path string, handler http.HandlerFunc) {
root := e.getRoot(method)
//是否已经在路由数上绑定,如果已经绑定就不在继续绑定
if _, ok := root.paths[path]; ok {
log.Default().Println(path, "is exist")
return
}
//将path与处理方法关系绑定
root.method = method
root.paths[path] = handler
}
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//对应method中的路由树
if tree, ok := e.trees[r.Method]; ok {
//路由数中path映射
if handler, ok := tree.paths[r.URL.Path]; ok {
handler(w, r)
return
}
}
//在路由数中没有找到对应的路由
w.Write([]byte("404 Not found!\n"))
}
// Get Get方法
func (e *Engine) Get(path string, handler http.HandlerFunc) {
e.addRoute(http.MethodGet, path, handler)
}
// Post Post方法
func (e *Engine) Post(path string, handler http.HandlerFunc) {
e.addRoute(http.MethodPost, path, handler)
}
// Default returns an Engine
func Default() *Engine {
return &Engine{trees: make(methodTrees, 2)}
}
// Run 启动方法start a http server
func (e *Engine) Run(addr string) {
err := http.ListenAndServe(addr, e)
if err != nil {
return
}
} - 首先定义了类型methodTrees,这是提供给框架用户的,用来定义路由映射的处理方法。我们在Engine中,添加了一张路由映射表router,key 由请求方法和静态路由地址构成,例如GET请求 “/“ 在methodTrees中methodTrees[“GET”][“/“]、”/hello”=>methodTrees[“GET”][“/hello”]、”/hello”=>methodTrees[“POST”][“/hello”],这样针对相同的路由,如果请求方法不同,可以映射不同的处理方法(Handler),value 是用户映射的处理方法。
- 当用户调用(*Engine).Get()方法时,会将路由和处理方法注册到映射表 router 中,(*Engine).Run()方法,是 ListenAndServe 的包装。
- Engine实现的 ServeHTTP 方法的作用就是,解析请求的路径,查找路由映射表,如果查到,就执行注册的处理方法。如果查不到,就返回 **404 Not found!**。
mai测试n方法调用
1 | package main |
curl请求测试
1 | ~ curl 127.0.0.1:8088/hello |
至此,整个Mygin框架的原型已经出来了。实现了路由映射表,提供了用户注册静态路由的方法,包装了启动服务的函数。当然,到目前为止,我们还没有实现比net/http标准库更强大的能力,不用担心,很快就可以将动态路由、中间件等功能添加上去了。