美文网首页
go-web框架封装之HTTP

go-web框架封装之HTTP

作者: 熊少年 | 来源:发表于2018-12-19 16:28 被阅读4次

    学习go也有一段时间了,整理了一下学习go的心得体会。结合一个web框架构建来体会一下。demo地址
    1 路由以及数据库连接

    func StartHttpServer() {
        r := mux.NewRouter()
        api := r.PathPrefix("/api").Subrouter()
        go func() {
            errs := http.ListenAndServe(":23456", r)
            if errs != nil {
                fmt.Println(errs)
            }
        }()
    
        AddHandlerApi(api)
        ch := make(chan os.Signal, 1)
        signal.Notify(ch)
        s := <-ch
        fmt.Println("Got signal:", s)
    }
    func AddHandlerApi(r *mux.Router) {
           // 利用工厂函数构建sql
        mysql, _ := db.NewMysqlService(db.IntConfig())
          // 路由划分  重点讲解 CenterCtol函数实现
        userApi, err := handler.NewUserHandler(mysql)
        if err != nil {
            fmt.Printf("userapi db connect is : %v", err)
        } else {
            r.HandleFunc("/login", util.CenterCtol(userApi.UserLogin, &dto.UserLoginReq{}))
            r.HandleFunc("/register", util.CenterCtol(userApi.UserRegister, &dto.UserReigisterReq{}))
            r.HandleFunc("/del_user", util.CenterCtol(userApi.DelUser, &dto.DelUserReq{})).Methods("POST")
            r.HandleFunc("/user_list", util.CenterCtol(userApi.UserList, &dto.GetUserListReq{})).Methods("GET")
        }
    }
    

    2 CenterCtol 对HTTP Res Req 封装

    
    type Response struct {
        Code int         `json:"code"` // status code
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    
        NotEscapeHtml bool `json:"-"`
    }
    type DtoHandler func(w http.ResponseWriter, r *http.Request)
    type HandlerFuncDto func(http.ResponseWriter, *http.Request, DtoAAA) *Response
    
    type DtoAAA interface {
        GetError() error
    }
    
    func CenterCtol(a HandlerFuncDto, b DtoAAA) http.HandlerFunc {
           // 在返回函数中处理
        return func(w http.ResponseWriter, r *http.Request) {
                 // 定义统一的返回数据
            var res = &Response{}
               //  返回处理函数
            defer func() {
                if res.Code == 0 {
                    res.Msg = "success"
                }
                            // header处理
                w.Header().Set("Access-Control-Allow-Origin", "*")
                w.Header().Set("Content-Type", "application/json")
                v, _ := json.Marshal(res)
                w.Write(v)
            }()
             // body处理
            if r != nil && r.Body != nil {
                defer r.Body.Close()
            }
    
            if err := r.ParseForm(); err != nil {
            }
                 // 定义统一的req数据接口
            var requestDto DtoAAA = nil
                // 接口数据处理
            if b != nil {
                          // 反射
                dtoType := reflect.TypeOf(b)
                requestDto = reflect.New(dtoType.Elem()).Interface().(DtoAAA)
                //json.Unmarshal(req, requestDto)
                           // 自定义解析函数(抄的)处理’application/x-www-form-urlencoded‘
                Unmarshal(r.Form, requestDto)
                err := requestDto.GetError()
                if err != nil {
                    res.Code = 1
                    res.Msg = fmt.Sprintf("err:%v", err)
                }
            }
                // 处理函数
            res = a(w, r, requestDto)
        }
    }
    
    

    3 对用户的增删改查

    // 结构体构建 引入需要的结构
    type UserHandler struct {
        ux *commonModel.UserSql
    }
    // 工厂函数创建实例
    func NewUserHandler(base *sql.DB) (*UserHandler, error) {
        db, err := commonModel.NewUserSql(base)
        if err != nil {
            return nil, err
        }
        return &UserHandler{
            ux: db,
        }, nil
    }
    // 以登录来讲
    func (db *UserHandler) UserLogin(w http.ResponseWriter, r *http.Request, req util.DtoAAA) *util.Response {
        res := &util.Response{}
        args := req.(*dto.UserLoginReq)
        user, err := db.ux.LoginSql(args.Username, args.Password)
        if err != nil {
            res.Code = 2
            res.Msg = fmt.Sprintf("sql err:%v", err)
            return res
        }
        res.Data = user
        return res
    }
    

    4 sql操作

    // 结构体
    type UserSql struct {
        sql *sql.DB
    }
    // 工厂函数
    func NewUserSql(config *sql.DB) (*UserSql, error) {
        return &UserSql{
            sql: config,
        }, nil
    }
    //登录方法
    func (db *UserSql) LoginSql(username string, password string) (*UserTable, error) {
        user := &UserTable{}
        mysql := fmt.Sprintf("select id,username,password,sex,age from %v where username=? and password=?", user_table)
        err := db.sql.QueryRow(mysql, username, password).Scan(&user.Id, &user.Username, &user.Password, &user.Sex, &user.Age)
        if err != nil {
            return nil, err
        }
        return user, nil
    }
    

    代码里面还有很多的细节,可以去细看,对于入门人员来说还是很值得一看的。

    换上自己的数据库地址

    func IntConfig() SqlConfig {
        sql := SqlConfig{
            Dsn:     "自己的数据库地址",
            MaxIdle: 11,
            MaxOpen: 11,
        }
        return sql
    }
    

    相关文章

      网友评论

          本文标题:go-web框架封装之HTTP

          本文链接:https://www.haomeiwen.com/subject/eqejkqtx.html