1.Gin 是什么?
Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,使用 Gin 吧。
2.Gin相关地址
0x1 快速开始1. 用module模式创建工程
mkdir web_api
cd web_api
go mod init web_api
2.创建main.go
import "github.com/gin-gonic/gin" func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
3. 运行
go run main.go
:8080/ping
0x2 实践
1. 说明
1)这是一个简单的例子,实现了通过id查找数据库获取用户名字的功能。
2)使用了MVC结构,当然也可以不套用这种结构。好处就是开发web程序结构会清晰很多。
3)使用了go modules的包管理方式确实方便很多。不清楚的可以看我另外一篇关于go modules的介绍https://www.cnblogs.com/mrblue/p/11277100.html
4)依赖了yml和gorm库
2.目录结构如下
│ config.yml
│ go.mod
│ go.sum
│ main.go
│ Makefile
│ README.md
├─app
│ app.go
│ handle.go
│ routers.go
│
├─controllers
│ user.go
│
├─models
│ model.go
│ user.go
│
├─routers
│ router.go
│
└─service
user.go
3.主要文件说明
1)app/app.go 应用程序文件,负责初始化gin上下文,处理信号量
package app import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"web_api/routers"
"github.com/gin-gonic/gin"
) type Config struct {
Port string
Debug bool
} func Run(cfg Config) {
router := gin.Default()
routes.RegisterRouters(router)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: router,
} go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}() quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutdown Server ...") ctx, cancel := context.WithTimeout(context.Background(), *time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
}
2) controllers/user.go 控制文件,获取请求参数,调用service的逻辑方法,然后返回结果
package controllers import (
"net/http" "web_api/service" "github.com/gin-gonic/gin"
) func GetName(c *gin.Context) { id := c.Param("id")
r := service.User{ID: id}
name, err := r.GetName()
if nil != err {
c.String(http.StatusInternalServerError, err.Error())
return
} c.JSON(http.StatusOK, gin.H{"error": "ok", "name": name})
}
3) models/model.go 数据库的初始化
package models import (
"fmt" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
) // Config 配置
type Config struct {
User string
Password string
Host string
Name string
} var (
db *gorm.DB
) // Setup initializes the database instance
func Setup(cfg Config) error { var err error
db, err = gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
cfg.User,
cfg.Password,
cfg.Host,
cfg.Name)) if err != nil {
return err
} db.SingularTable(true)
db.DB().SetMaxIdleConns()
db.DB().SetMaxOpenConns()
return nil
} // CloseDB closes database connection (unnecessary)
func CloseDB() {
defer db.Close()
}
4) models/user.go user数据库表的增删改查
package models import (
"github.com/jinzhu/gorm"
) type User struct {
ID string `gorm:"primary_key;type:INT(20)"`
Age int32 `gorm:"type:INT(20)"`
Name string `gorm:"type:VARCHAR(256)"`
Desc string `gorm:"type:VARCHAR(256)"`
}
func GetUser(id string) (*User, error) {
u := &User{
ID: id,
}
err := db.First(u).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
} return u, nil
}
5) routers/router.go 定义路由
package routers import (
"web_api/controllers" "github.com/gin-gonic/gin"
) // RegisterRouters ...
func RegisterRouters(g *gin.Engine) {
g.GET("/name/:id", controllers.GetName)
}
6) service/user.go user的逻辑
package service import (
"web_api/models"
) type User struct {
ID string
} func (r *User) GetName() (string, error) {
u, err := models.GetUser(r.ID)
if nil != err {
return "", err
}
return u.Name, nil
}
7) main.go
package main import (
"flag"
"io/ioutil"
"log" "web_api/app"
"web_api/models" "gopkg.in/yaml.v2"
) // Config 配置
type Config struct {
App app.Config
Model models.Config
} var (
cfgPath = flag.String("config", "config.yml", "config file path")
) func main() {
cfg := Config{}
if data, err := ioutil.ReadFile(*cfgPath); nil != err {
panic(err)
} else {
if err := yaml.Unmarshal(data, &cfg); nil != err {
panic(err)
}
} if err := models.Setup(cfg.Model); nil != err {
panic(err)
} app.Run(cfg.App) log.Println("Server exiting")
}
4.配置文件 confg.yml
app:
port:
debug: true model:
user: root
password: xxxxx
host: 127.0.0.1:
name: mydb
5.测试
1)需要你的mysql有个叫mydb的库,里有一张叫user的表
2)查找id魏1000的人的名字,浏览器打开 http://127.0.0.1:8080/name/1000