跳至主要內容

第二天:封装Context

程序员李某某原创Golang框架源码上下文大约 1 分钟

第二天:封装Context

痛点分析

我们现在的处理函数入参是 http.ResponseWriter, *http.Request 每个接口的处理需要设置太多的参数,粒度太细 比如,响应头(状态码,响应格式),响应状态码,响应体

支持restfull请求,就需要解析路径上的参数,需要存储

我们就需要根据以上的需求,封装为context

封装

先定义这个结构体

type Context struct {
	Writer     http.ResponseWriter
	Req        *http.Request
	StatusCode int
	Path       string
}

尝试做一个类似gin的参数获取

// 表单
func (ctx *Context) PostForm(k string) string {
	return ctx.Req.FormValue(k)
}

func (ctx *Context) Query(k string) string {
	return ctx.Req.URL.Query().Get(k)
}

响应头

func (ctx *Context) Status(code int) {
	ctx.StatusCode = code
	ctx.Writer.WriteHeader(code)
}

func (ctx *Context) SetHeader(k, v string) {
	ctx.Writer.Header().Set(k, v)
}

响应体

func (ctx *Context) JSON(code int, body interface{}) {
	ctx.SetHeader("Content-Type", "application/json")
	ctx.Status(code)
	if bytes, err := json.Marshal(body); err != nil {
		http.Error(ctx.Writer, err.Error(), 500)
	} else {
		_, err = ctx.Writer.Write(bytes)
		if err != nil {
			http.Error(ctx.Writer, err.Error(), 500)
		}
	}
}

func (ctx *Context) String(code int, format string, v ...interface{}) {
	ctx.SetHeader("Content-Type", "text/plain")
	ctx.Status(code)
	if _, err := ctx.Writer.Write([]byte(fmt.Sprintf(format, v...))); err != nil {
		http.Error(ctx.Writer, err.Error(), 500)
	}
}

为了使用更简洁,定义一个别名

type H map[string]interface{}

调整入参

我们还差将处理函数入参改为Context

// type HandleFunc func(http.ResponseWriter, *http.Request)
type HandleFunc func(*Context)
// 只有 ServeHTTP 方法报错,改了就行
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	k := r.Method + "_" + r.URL.Path
	ctx := &Context{
		Req:    r,
		Writer: w,
	}
	if handleFunc, ok := e.router[k]; ok {
		handleFunc(ctx)
	} else {
		ctx.String(http.StatusNotFound, "404 NOT FOUND: %s\n", ctx.Path)
	}
}

测试

func main() {

	e := lee.New()
	e.Get("/sayHello", handleFunc)
	e.Run("localhost:8080")
}

func handleFunc(ctx *lee.Context) {

	ctx.JSON(200, lee.H{
		"code": 200,
		"msg":  "成功",
		"data": lee.H{
			"name": "lll",
			"age":  18,
		},
	})
}
上次编辑于:
贡献者: ext.liyuanhao3