之前,已经讲过很多Golang的东西,比如基础语法,mysql的使用,redis的使用等等,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html,

今天就用从头写一个完整的go的示例项目吧。

本项目完全使用原生开发,没有使用任何WEB框架和ORM。虽然大家对mvc 呀,三层架构已经很了解了。但是,我还是想从头写一个完整的示例项目。这样大家有一个更深刻的了解,这样以后介绍web框架,orm框架的时候,学习起来应该会简单一点。

项目架构

下图这种架构模式相信大家应该十分清楚

Controller组合封装

Controller"基类"封装

package frameworktype Controller struct {   Data interface{}}

UserController定义了用户注册,登录和查询等简单的三个接口

package controllerimport (   "net/http"   "micro-cloud/service"   "micro-cloud/utils"   "micro-cloud/framework")/** * r.PostFormValue  : 可以解析 Post/PUT Content-Type=application/x-www-form-urlencoded 或 Content-Type=multipart/form-data */type UserConterller struct {}var userService = new(service.UserService)func (p *UserConterller) Router(router *framework.RouterHandler) {   router.Router("/register", p.register)   router.Router("/login", p.login)   router.Router("/findAll", p.findAll)}//POST Content-Type=application/x-www-form-urlencodedfunc (p *UserConterller) register(w http.ResponseWriter, r *http.Request) {   username := r.PostFormValue("username")   password := r.PostFormValue("password")   if utils.Empty(username) || utils.Empty(password) {      microcloud.ResultFail(w, "username or password can not be empty")      return   }   id := userService.Insert(username, password)   if id <= 0 {      microcloud.ResultFail(w, "register fail")      return   }   microcloud.ResultOk(w, "register success")}//POST Content-Type=application/x-www-form-urlencodedfunc (p *UserConterller) login(w http.ResponseWriter, r *http.Request) {   username := r.PostFormValue("username")   password := r.PostFormValue("password")   if utils.Empty(username) || utils.Empty(password) {      microcloud.ResultFail(w, "username or password can not be empty")      return   }   users := userService.SelectUserByName(username)   if len(users) == 0 {      microcloud.ResultFail(w, "user does not exist")      return   }   if users[0].Password != password {      microcloud.ResultFail(w, "password error")      return   }   microcloud.ResultOk(w, "login success")}// GET/POSTfunc (p *UserConterller) findAll(w http.ResponseWriter, r *http.Request) {   users := userService.SelectAllUser()   framework.ResultJsonOk(w, users)}

数据访问层

package daoimport (    "micro-cloud/model"    "fmt"    )type UserDao struct {}func (p *UserDao) Insert(user *model.User) int64 {    result, err := framework.DB.Exec("INSERT INTO user(`username`,`password`,`create_time`) value(?,?,?)", user.Username, user.Password, user.CreateTime)    if err != nil {        fmt.Println("Insert error")        return 0    }    id, err := result.LastInsertId()    if err != nil {        fmt.Println("Insert error")        return 0    }    return id}func (p *UserDao) SelectUserByName(username string) []model.User {    rows, err := framework.DB.Query("SELECT * FROM user WHERE username = ?", username)    if err != nil {        fmt.Println("selectuserbyname error")        return nil    }    var users []model.User    for rows.Next() {        var user model.User        err := rows.Scan(&user.ID, &user.Username, &user.Password, &user.CreateTime)        if err != nil {            fmt.Println("selectuserbyname error")            continue        }        users = append(users, user)    }    rows.Close()    return users}func (p *UserDao) SelectAllUser() []model.User {    rows, err := framework.DB.Query("SELECT * FROM user")    if err != nil {        fmt.Println("SelectAllUser error")        return nil    }    var users []model.User    for rows.Next() {        var user model.User        err := rows.Scan(&user.ID, &user.Username, &user.Password, &user.CreateTime)        if err != nil {            fmt.Println("SelectAllUser error")            continue        }        users = append(users, user)    }    rows.Close()    return users}

实体层

package modelimport "time"type User struct {    ID         uint      `json:"id"`    Username   string    `json:"username"`    Password   string    `json:"-"`    CreateTime time.Time `json:"create_time"`}

database

数据库操作类的实现

package microcloudimport (    "database/sql"    "log"    "strings"    _ "github.com/go-sql-driver/mysql")//数据库的配置const (    username   = "admin"    password   = "123456"    ip         = "10.2.1.5"    port       = "3306"    dbName     = "microcloud"    driverName = "mysql")//DB数据库连接池var DB *sql.DBfunc InitDB() {    //构建连接:"用户名:密码@tcp(IP:端口)/数据库?charset=uft8"    //注意:要想解析time.Time类型,必须要设置parseTime=True    path := strings.Join([]string{username, ":", password, "@tcp(", ip, ":", port, ")/", dbName, "?charset=utf8&parseTime=True&loc=Local"}, "")    //打开数据库,前者是驱动名,所以要导入:_"github.com/go-sql-driver/mysql"    DB, _ = sql.Open(driverName, path)    //设置数据库最大连接数    DB.SetConnMaxLifetime(100)    //设置数据库最大闲置连接数    DB.SetMaxIdleConns(10)    //验证连接    if err := DB.Ping(); err != nil {        log.Panic(err)    }    log.Println("database connect success")}func CreateTable() {    userTable := "CREATE TABLE IF NOT EXISTS `user`(" +        "`id` INT UNSIGNED AUTO_INCREMENT," +        "`username` VARCHAR(20) NOT NULL," +        "`password` VARCHAR(40) NOT NULL," +        "`create_time` DATETIME," +        "PRIMARY KEY ( `id` )" +        ")ENGINE=InnoDB DEFAULT CHARSET=utf8;"    _, err := DB.Exec(userTable)    if err != nil {        log.Panic(err)    }}

http

http server的实现

server := &http.Server{        Addr:        ":8215",        Handler:     microcloud.Router,        ReadTimeout: 5 * time.Second,    }    RegiterRouter(microcloud.Router)    err := server.ListenAndServe()    if err != nil {        log.Panic(err)    }

Router

路由处理的实现,其实也就是一个转发的功能

type RouterHandler struct {}var mux = make(map[string]func(http.ResponseWriter,*http.Request))func (p *RouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    fmt.Println(r.URL.Path)    if fun, ok := mux[r.URL.Path]; ok {        fun(w, r)        return    }    //静态资源    if strings.HasPrefix(r.URL.Path,constant.STATIC_BAES_PATH){        if fun, ok := mux[constant.STATIC_BAES_PATH]; ok {            fun(w, r)            return        }    }    http.Error(w, "error URL:"+r.URL.String(), http.StatusBadRequest)}func (p *RouterHandler) Router(relativePath string, handler func(http.ResponseWriter, *http.Request)) {    mux[relativePath] = handler}

演示

执行 go run main.go 之后,打开Postman,调相关的接口

以下就是访问API的请求与响应

/findAll 接口

/register 接口

最后

以上,用Go语言实现webapi 的例子,已经介绍完了,虽然比较简单,session,权限验证等都没有加。但是最主要的功能已经讲完了,感兴趣的可以从头编写下相关的代码。

完整例子下载:microcloud.rar

VBS 请求WebAPI接口_从零开始实现简单的webapi框架【Golang 入门系列十一】相关推荐

  1. WebApi接口 - 如何在应用中调用webapi接口

    » 简单做个webapi(查询+添加)接口 首先,我们需要有一个webapi接口项目,我这里以前面WebApi接口 - 响应输出xml和json文章的项目来构建本篇文章的测试用例:这里新建一个 DbD ...

  2. “机器学习”三重门_“中庸之道”趋若人(深度学习入门系列之四)

    原文链接   更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 系列文章: 一入侯门"深"似海,深度学习深几许(深度学习入门系列之一) 人工& ...

  3. VBS 请求WebAPI接口_如何设计WEB API

    前言 我一直认为WEB API设计是后端工程师的活,对WEB API设计规范理解的不是很深,正是因为之前看过不同后端工程师的Web API设计难以对接前端产品,导致经常需要修改接口,浪费了很多时间,专 ...

  4. 请求令牌 接口_时序图说明JWT用户认证及接口鉴权的细节

    JWT用户认证及接口鉴权的细节以及原理 一.回顾JWT的授权及鉴权流程 在笔者的上一篇文章中,已经为大家介绍了JWT以及其结构及使用方法.其授权与鉴权流程浓缩为以下两句话: 授权:使用可信用户信息(用 ...

  5. java 多态 接口_从零开始的Java日常: 多态,抽象类,接口

    欢迎关注微博:@小白程序员的日常 欢迎关注微博超话:#小白程序员的日常# 本人目前在自学java,会不间断更新java知识 同为小白或者有大佬可以一起探讨一下 一.多态 1.什么是多态 同一个对象,在 ...

  6. java springmvc 数据库事务_事务的简单回顾_JavaEE框架(Maven+SpringMvc+Spring+MyBatis)全程实战教程_Java视频-51CTO学院...

    SpringMVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring MVC 分离了控制器.模型对象.分派器以及处理程序对象 ...

  7. mysql可以使用mybaties框架吗_搭建一个简单的mybatis框架

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  8. golang 热插拨 插件_从零开始实现一个插件化框架(一)

    欢迎关注专栏:里面定期分享Android和Flutter架构技术知识点及解析,还会不断更新的BATJ面试专题,欢迎大家前来探讨交流,如有好的文章也欢迎投稿. Flutter跨平台开发终极之选​zhua ...

  9. java插件化_从零开始实现一个插件化框架(一)

    欢迎关注专栏:里面定期分享Android和Flutter架构技术知识点及解析,还会不断更新的BATJ面试专题,欢迎大家前来探讨交流,如有好的文章也欢迎投稿.Flutter跨平台开发终极之选​zhuan ...

最新文章

  1. IOS之TableViewCell重用机制避免重复显示问题
  2. linux回调函数的使用
  3. 如何找出电脑里的流氓软件_啥拦截软件都挡不住?教你一键揪出乱弹窗的流氓软件...
  4. c语言递归最小值,递归求最大最小值算法 分治策略(c语言实现)
  5. artificial intelligence courses
  6. 深入了解以太坊虚拟机第5部分——一个新合约被创建后会发生什么
  7. Springboot启动完毕后提供了立刻执行自定义程序的两个接口类
  8. 日常见到一些命令使用实例~(持续更新!)
  9. 结合中断分析TCP/IP协议栈在LINUX内核中的运行时序
  10. 【图像隐写】基于matlab GUI DWT与SVD数字水印 【含Matlab源码 253期】
  11. mysql to sqlserver_mysql to sqlserver
  12. 基于SSM的网上书城系统设计与实现
  13. html、css合并表格边框
  14. eclipse jdt
  15. 今日头条有麻烦了!App 被下架
  16. loj534. 「LibreOJ Round #6」花团
  17. 【html】edm 邮件制作指南
  18. javaweb基于SSM开发房屋租赁管理系统(房东 租客两种用户) 课程设计 大作业源码 毕业设计
  19. Java Swing界面设计UI(全)
  20. Linux常用命令大全,一篇搞定

热门文章

  1. oracle move不能操作分区,关于Oracle分区表的move操作
  2. 大学老师必备!30余个学术资源网站速收藏(附链接)
  3. COMSOL弱形式解微分方程
  4. 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL
  5. p值 统计学意义_什么是统计意义? P值定义以及如何计算
  6. TDM与FDM的比较
  7. 前端例程20210731:圆形表盘时钟布局实现
  8. 快速回到桌面的快捷键快速切换窗口快捷键
  9. Glusterfs全局统一命名空间
  10. Go语言的流程结构简单介绍