五步用golang封装自己web框架httper:第五步,实现http.handler接口
我们知道,实现一个接口所有方法,就是该接口
golang内置库http内http.HandlerFunc就是http.Handler接口的一种实现,为此我们可以用以下方法实现http.Handler接口
- ContextHandle
- ErrorHandle
- ResultHandle
读者可以对比测试文件,使用符合自己使用习惯的实现
ContextHandle,类似gin
该实现只封装http.ResponseWriter,*http.Request
handle/context.go
type ContextHandle func(c httper.Context)
func (ch ContextHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := httper.NewContext(w, r) ch(c)
}
ErrorHandle,统一错误处理,类似echo
handle/error.go
type ErrorHandle func(c httper.Context) error
func (eh ErrorHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := httper.NewContext(w, r) err := eh(c) UnitErrorHandle(c, err)}
var UnitErrorHandle = func(c httper.Context, err error) {
if err == nil {
return
}
http.Error(c.Writer(), err.Error(), http.StatusInternalServerError)
}
ResultHandle,统一结果处理,类似node.js的express
篇幅关系,result接口及其实现不在此处赘述。详细请看 Golang接口?类型!
handle/result.go
type ResultHandle func(c httper.Context) result.Result
func (rh ResultHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := httper.NewContext(w, r)
rs := rh(c)
UnitResultHandle(c, rs)
}
var UnitResultHandle = func(c httper.Context, rs result.Result) {
if rs == nil {
return
}
status := http.StatusOK
m := make(map[string]any)
if rs.Error() != nil || rs.Code() != result.Success {
status = http.StatusInternalServerError
m["error"] = rs.Error().Error()
}
if msg := result.MapCodeMessage[rs.Code()]; msg != "" {
m["message"] = msg
}
if rs.Data() != nil {
m["data"] = rs.Data()
}
m["code"] = rs.Code()
err := c.JSON(status, m)
if err != nil {
http.Error(c.Writer(), err.Error(), http.StatusInternalServerError)
}
}
测试
func TestHandle(t *testing.T) {
data := struct {
Hello string `json:"hello"`
}{
Hello: "world",
}
mux := httper.New()
mux.POST("/context", handle.ContextHandle(func(c httper.Context) {
err := c.BindJson(&data)
if err != nil {
_ = c.Error(http.StatusBadRequest, err)
return
}
err = c.JSON(http.StatusOK, data)
if err != nil {
_ = c.Error(http.StatusInternalServerError, err)
return
}
}))
mux.POST("/error", handle.ErrorHandle(func(c httper.Context) error {
err := c.BindJson(&data)
if err != nil {
return c.Error(http.StatusBadRequest, err)
}
return c.JSON(http.StatusOK, data)
}))
mux.POST("/result", handle.ResultHandle(func(c httper.Context) result.Result {
err := c.BindJson(&data)
if err != nil {
return result.ErrBadRequest.With(err)
}
return result.Map{
"hello": data.Hello,
}
}))
for r, f := range mux.Routes() {
t.Log("register router:", r, f)
}
t.Fatal(mux.Start(":8000"))
}
本作品采用《CC 协议》,转载必须注明作者和本文链接