Golang - Gin框架学习笔记

Gin简介

1.Gin 是什么?

Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,可以使用 Gin 。

2.Gin特点

轻量级、高性能(使用httprouter)、中文文档齐全、简单易用。

3.Gin相关地址

doc:https://gin-gonic.com/zh-cn/docs/

github:https://github.com/gin-gonic/gin

快速开始

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(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}
复制代码

3. 运行

go run main.go

4. 浏览器打开 127.0.0.1:8080/ping

实践

1. 说明

1)这是一个简单的例子,实现了通过id查找数据库获取用户名字的功能。

2)使用了MVC结构,当然也可以不套用这种结构,好处就是开发web程序结构会清晰很多。

3)使用了go modules的包管理方式,确实很方便。

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(), 10*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(56)
    db.DB().SetMaxOpenConns(128)
    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 (User) TableName() string {
    return "user"
  }

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: 8080
  debug: true
model:
  user: root
  password: xxxxx
  host: 127.0.0.1:3306
  name: mydb
复制代码

5.测试

1)需要你的mysql有个叫mydb的库,里有一张叫user的表

2)查找id为1000的人的名字,浏览器打开 http://127.0.0.1:8080/name/1000

posted @   李若盛开  阅读(525)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示