之前,已经讲过很多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-urlencoded
func (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-urlencoded
func (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/POST
func (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.Userfor rows.Next() {var user model.Usererr := 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.Userfor rows.Next() {var user model.Usererr := 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=Truepath := 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[rela

演示

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

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

/findAll 接口

/register 接口

最后

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

完整例子下载:microcloud.rar

Golang 入门系列(十一)Go语言实现webapi相关推荐

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

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

  2. Golang 入门系列(九) 如何读取YAML,JSON,INI等配置文件...

    实际项目中,读取相关的系统配置文件是很常见的事情.今天就来说一说,Golang 是如何读取YAML,JSON,INI等配置文件的. 1. json使用 JSON 应该比较熟悉,它是一种轻量级的数据交换 ...

  3. Golang 入门系列(十) mysql数据库的使用

    之前,已经讲过一些Golang的基础的东西,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html, 今天简 ...

  4. 快速入门系列之 Rust 语言 GitChat连接

    Rust 是一枚新星,兼顾开发效率和执行效率的语言.本文以实例为导向,讲解 Rust 这门语言,适合有一定其他面向对象语言基础的人员快速入门. 本文将讲解如下内容: - Hello World 从头起 ...

  5. 快速入门系列之 Scala 语言 GitChat连接

    Scala 是一门多范式的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性.目前常应用于 Spark.后端开发等,Twitter 等公司也选择其作为后端语言. 本文以实例为导向,讲解 Sc ...

  6. ABP入门系列(16)——通过webapi与系统进行交互

    1. 引言 上一节我们讲解了如何创建微信公众号模块,这一节我们就继续跟进,来讲一讲公众号模块如何与系统进行交互. 微信公众号模块作为一个独立的web模块部署,要想与现有的[任务清单]进行交互,我们要想 ...

  7. Go 语言入门系列:基本语法介绍之变量的声明与初始化

    各位同学端午安康! 前文回顾 前面的文章介绍了 Go 相关的特性与入门案例,对于一门编程语言,变量和语法是我们首先需要掌握的.Go 在语法上与 C 语言有很多相似支持,但是比 C 语言更加简约.如果你 ...

  8. golang 切片 接口_Go 经典入门系列 18:接口(一)

    点击上方蓝色"Go语言中文网"关注,每天一起学 Go 欢迎来到 Golang 系列教程[1]的第 18 个教程.接口共有两个教程,这是我们接口的第一个教程. 什么是接口? 在面向对 ...

  9. C语言入门系列 -运算符

    C语言入门系列 - 运算符 第一节 C 语言基础以及基本数据类型 第二节 C 语言运算符 第三节 C 语言控制语句 第四节 C 语言自定义函数 第五节 C 语言修饰变量的关键字 第六节 C 语言构造数 ...

最新文章

  1. 5中排序算法(冒泡,选择,插入,快速,归并)
  2. C++(STL):02---tuple容器
  3. 关于html标签元素的data-*属性
  4. 95-138-010-源码-Function-AggregateFunction
  5. Nginx服务器的开发团队
  6. python删除文件夹下文件夹_python删除指定文件夹下文件和文件夹的方法详解
  7. 《C Primer Plus》读书笔记
  8. 从零开始的Unity萌导书#1:Hello,Unity!
  9. cat 大众点评 mysql_大众点评-CAT监控平台
  10. vcredist_x86.exe 静默安装方法
  11. 李阳疯狂英语助教工作总结
  12. 【应用层】DNS协议
  13. 如何查看Android keystore 签名信息
  14. 了解V模型,W模型,H模型
  15. 13.6.3 程序案例:BLE低功耗蓝牙调试助手
  16. ehshig蒙文歌曲_ehshig蒙文歌曲下载
  17. WCF学习——掀开你的盖头来
  18. ios中wallproxy使用教程
  19. JAVA-extends
  20. LINK : fatal error LNK1104: 无法打开文件“opencv_world400d.lib”---VS2017+OpenCV配置过程

热门文章

  1. 4.云计算和大数据时代网络揭秘-安全的网络通道-网络加密
  2. ZOJ-2342 Roads 二分图最小权值覆盖
  3. Internet Explorer 9 新功能:固定并快速打开常用网站
  4. RSync服务器配置
  5. 如何实现共享软件网络授权认证,包括注册新用户、登录、修改密码等操作
  6. 光纤通道(FC: Fibre Channel)
  7. vocabulary of ERP
  8. Idea Marketplace 加载很慢 加载不出来
  9. gRPC-go 入门(1):Hello World
  10. 1、配置PHP构建环境