[Golang] Gin框架學習筆記


 

0x0 Gin簡介

1.Gin 是什么?

Gin 是一個用 Go (Golang) 編寫的 HTTP web 框架。 它是一個類似於 martini 但擁有更好性能的 API 框架, 由於 httprouter,速度提高了近 40 倍。如果你需要極好的性能,使用 Gin 吧。

2.Gin相關地址

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

github:https://github.com/gin-gonic/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(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

 

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(), 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM