Gin是一个使用Go语言开发的Web框架。
它提供类似Martini的API,但性能更佳,速度提升高达40倍。
如果你是性能和高效的追求者, 你会爱上 Gin。
快速
基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。支持中间件
传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。Crash 处理
Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!JSON 验证
Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。路由组
Gin帮助您更好地组织您的路由,例如,按照需要授权和不需要授权和不同API版本进行分组。此外,路由分组可以无限嵌套而不降低性能。错误管理
Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。内置渲染
Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。可扩展性
新建一个中间件非常简单
原始项目
package main
import(
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type Todo struct{
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
var(
DB *gorm.DB
)
func InitMySql() (err error) {
dsn := "root:root123@tcp(127.0.0.1:3306)/list?charset=utf8mb4&parseTime=True&loc=Local"
DB1, err := gorm.Open("mysql", dsn)
if err != nil {
return
}
DB = DB1
return DB1.DB().Ping()
}
func main(){
//连接数据库
err := InitMySql()
if err != nil{
panic(err)
}
defer DB.Close()
//定义路由
r := gin.Default()
r.Static("/static", "static")
r.LoadHTMLGlob("templates/*")
r.GET("/", controller.IndexHandler)
v1Group := r.Group("v1")
{
v1Group.POST("/todo", function(c *gin.Context){ ... })
v1Group.GET("/todo", function(c *gin.Context){ ... })
v1Group.PUT("/todo/:id", function(c *gin.Context){ ... })
v1Group.DELETE("/todo/:id", function(c *gin.Context){ ... })
}
r.Run()
}
拆分目标和步骤
dao 主要用于数据库等的连接初始化
model 主要用于数据的curd
controller 主要用于路由中绑定的处理过程
router 主要用于封装路由列表
1、dao(dao\mysql.go)主要用于数据库等的连接初始化
package dao
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var(
DB *gorm.DB
)
func Close() {
DB.Close()
}
func InitMySql() (err error) {
dsn := "root:root123@tcp(127.0.0.1:3306)/list?charset=utf8mb4&parseTime=True&loc=Local"
DB1, err := gorm.Open("mysql", dsn)
if err != nil {
return
}
DB = DB1
return DB1.DB().Ping()
}
2、model(model\todo.go)
package model
import (
"list/dao"
)
type Todo struct{
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
func CreateATodo(todo *Todo) (err error) {
err = dao.DB.Create(&todo).Error
return
}
func GetTodoList() (todoList []*Todo, err error){
if err = dao.DB.Find(&todoList).Error; err != nil{
return nil, err
}
return
}
func GetATodo(id string)(todo *Todo, err error) {
todo = new(Todo)
if err = dao.DB.Where("id=?", id).First(todo).Error; err != nil{
return nil, err
}
return
}
func UpdateATodo(todo *Todo)(err error) {
err = dao.DB.Save(todo).Error
return
}
func DeleteATodo(id string) (err error){
err = dao.DB.Where("id=?" , id).Delete(&Todo{}).Error
return
}
3、controller(controller\controller.go)
package controller
import (
"github.com/gin-gonic/gin"
"list/model"
)
func IndexHandler(c *gin.Context) {
c.HTML(200, "index.html", nil)
}
func CreateATodo(c *gin.Context) {
var todo model.Todo
c.BindJSON(&todo)
if err := model.CreateATodo(&todo); err != nil{
c.JSON(200, gin.H{"error": err.Error()})
}else{
c.JSON(200, todo)
}
}
func GetTodoList(c *gin.Context) {
if todoList, err := model.GetTodoList(); err != nil{
c.JSON(200, gin.H{"error": err.Error()})
}else{
c.JSON(200, todoList)
}
}
func UpdateATodo(c *gin.Context) {
id,ok := c.Params.Get("id")
if !ok{
c.JSON(200, gin.H{"error":"缺少id"})
return
}
todo,err := model.GetATodo(id)
if err != nil{
c.JSON(200, gin.H{"error":"查找失败"})
return
}
c.BindJSON(&todo)
if err2 := model.UpdateATodo(todo); err2 != nil{
c.JSON(200, gin.H{"error": err2.Error()})
}else{
c.JSON(200, todo)
}
}
func DeleteATodo(c *gin.Context) {
id, ok := c.Params.Get("id")
if !ok {
c.JSON(200, gin.H{"error":"missing id"})
return
}
if err := model.DeleteATodo(id); err != nil{
c.JSON(200, gin.H{"error:":err.Error()})
}else{
c.JSON(200, gin.H{"msg":"删除成功"})
}
}
4、router(router\router.go)
package routers
import (
"github.com/gin-gonic/gin"
"list/controller"
)
func SetUpRoute() *gin.Engine {
r := gin.Default()
r.Static("/static", "static")
r.LoadHTMLGlob("templates/*")
r.GET("/", controller.IndexHandler)
v1Group := r.Group("v1")
{
v1Group.POST("/todo", controller.CreateATodo)
v1Group.GET("/todo", controller.GetTodoList)
v1Group.PUT("/todo/:id", controller.UpdateATodo)
v1Group.DELETE("/todo/:id", controller.DeleteATodo)
}
return r
}
main.go
package main
import(
"list/dao"
"list/model"
"list/routers"
)
func main() {
err := dao.InitMySql()
if err != nil{
panic(err)
}
defer dao.Close()
dao.DB.AutoMigrate(&model.Todo{})
r := routers.SetUpRoute()
r.Run()
}
可以看到main.go代码清爽了很多