时间:2023-07-05 14:48:01 | 来源:网站运营
时间:2023-07-05 14:48:01 来源:网站运营
Go学习笔记 试着做一个Web框架:Go语言的Web框架有非常多,在日常开发中使用的有: beego、gin、revel等。这些框架也是一部分初学者的起点,这个系列的文章将会记录一个Web框架的开发历程。package mainimport ( "net/http")func main() { http.HandleFunc("/ping", pingHandlerFunc) http.ListenAndServe(":9527", nil)}func pingHandlerFunc(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong"))}
这里发现有三个点,一个是main函数中的http.HandleFunc方法,另一个是http.ListenAndServe,最后是pingHandlerFunc。type ( // Router is the registry of all registered routes for an `Echo` instance for // request matching and URL path parameter parsing. Router struct { tree *node routes map[string]*Route echo *Echo } node struct { //省略了node的内容 } kind uint8 children []*node methodHandler struct { //这里是存放不同method的handler func的,省略一些内容 get HandlerFunc })
因为一开始并不想搞得太复杂,这里暂时使用slice来保存。type Router struct { // 路由表 Handlers []*RouterMapping}
pattern与handler func存在着映射关系(路由表),这里可以用map的数据结构存储,在这里使用一个struct来作为Entity来保存映射的关系。type RouterMapping struct { Pattern string HandlerFunc RequestHandler}
Handler Func// Context is the most important part of gin. It allows us to pass variables between middleware,// manage the flow, validate the JSON of a request and render a JSON response for example.type Context struct { Request *http.Request Writer ResponseWriter}
Context的生存周期通常贯穿整个请求-响应的过程。type Context struct { Writer http.ResponseWriter Request *http.Request}
定义一个type,这是用户需要实现的Handler Functype RequestHandler func(context *Context)
到目前,我们已经将go的Handler Func包装完成。type Engine struct { delims render.Delims HTMLRender render.HTMLRender FuncMap template.FuncMap trees methodTrees maxParams uint16}
按照设计的思路,编写代码:type Engine struct { Router *Router}
添加RunAndListen方法,这里需要将之Router中的路由表项(Handlers)进行注册。func (e *Engine) RunAndListen(addr string) { for _, handler := range e.Router.Handlers { http.HandleFunc(handler.Pattern, func(writer http.ResponseWriter, request *http.Request) { handler.HandlerFunc(&Context{ Writer: writer, Request: request, }) }) } log.Fatal(http.ListenAndServe(addr, nil))}
测试一下:func TestRunAndListen() { e := NewEngine() e.Router.AddHandler("/ping", func(context *Context) { data := map[string]interface{}{ "say":"pong", } rawData,err := json.Marshal(data) if err != nil { panic(err) } context.Writer.Header().Set("Content-Type","application/json") context.Writer.Write(rawData) }) e.RunAndListen(":8090")}
访问 http://localhost:8090/ping就能看到{ "say": "pong"}
关键词:学习,笔记