Go 語(yǔ)言腳手架 - 使用 Gin 幾分鐘搭建具有繼承特性的對(duì)象

Go 語(yǔ)言有非常的優(yōu)秀的特性 (比如高并發(fā)、原生支持協(xié)程、泛型等等), 同時(shí)也貢獻(xiàn)了非常多項(xiàng)目(可以 https://awesome-go.com/ 一覽),在 Web 開(kāi)發(fā)這塊也有非常多優(yōu)秀的框架,如 Gin、Beego、Iris、Echo、Revel 等.
Top Go Web Frameworks

Gin

官方介紹
Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.

Skeleton (腳手架)

為了快速使用 Gin, 我提供了 Gin Skeleton 程序。
提供如下功能:

  • ORM 封裝 (使用的 GORM, 對(duì) Model Interface 可進(jìn)行繼承設(shè)計(jì), 可方便的封裝 DAO 層)
  • Tracing (支持鏈路追蹤)
  • Http TimeOut (支持 Http 請(qǐng)求超時(shí)中斷)
  • 數(shù)據(jù)庫(kù)連接池
  • Redis 集群支持

支持部署:

  • Docker
  • Helm

ORM Interface 繼承

設(shè)計(jì) BaseModel, 在后面的業(yè)務(wù) Model 繼承這個(gè) BaseModel 即可抽象 DAO interface


// base model
type BaseModel struct {
    ID        uint64 `json:"id,omitempty" gorm:"primarykey"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt `gorm:"index"`
}

// base dao
type BaseDAO interface {
    Create(entity interface{}) error
    Update(entity interface{}, uid uint64) (int64, error)
    Delete(entity interface{}, uid uint64) (int64, error)
    FindAll(entity interface{}, opts ...DAOOption) error
    FindByKeys(entity interface{}, keys map[string]interface{}) error
    FindByPages(entity interface{}, currentPage, pageSize int) error
    FindByPagesWithKeys(entity interface{}, keys map[string]interface{}, currentPage, pageSize int) error
    SearchByPagesWithKeys(entity interface{}, keys, keyOpts map[string]interface{}, currentPage, pageSize int) error
    Count(entity interface{}, count *int64) error
    CountWithKeys(entity interface{}, count *int64, keys, keyOpts map[string]interface{}) error
}

如 UserDAO 繼承 BaseDAO, 然后編寫(xiě) UserDAO 獨(dú)有的業(yè)務(wù) dao 方法


// instance entity
type User struct {
    ID           uint64         `json:"id,omitempty"`
    Name         string         `json:"name,omitempty" gorm:"type:varchar(255)"`
    Password     string         `json:"password,omitempty" gorm:"type:varchar(1000)"`
    Email        string         `json:"email,omitempty" gorm:"type:varchar(255)"`
    Age          int            `json:"age,omitempty"`
    Birthday     time.Time      `json:"birthday,omitempty"`
    MemberNumber sql.NullString `json:"member_number,omitempty" gorm:"type:varchar(255)"`
    Role         string         `json:"Role,omitempty" gorm:"type:varchar(100)"`
    BaseModel
}

// user DAO
type UserDAO interface {
    BaseDAO
    FindAllByCount(count int) ([]User, error)
}

新建的對(duì)象都可以繼承 BaseModel,這樣可以方便擴(kuò)展通用屬性和方法 。

Http Timeout

設(shè)計(jì) TimeoutHandler middleware 來(lái)處理超時(shí)請(qǐng)求

const (
    TIME_DURATION = 10
)

func DefinitionRoute(router *gin.Engine) {
    // set run mode
    gin.SetMode(gin.DebugMode)
    // middleware
    router.Use(middleware.Tracing())
    router.Use(middleware.UseCookieSession())
    router.Use(middleware.TimeoutHandler(time.Second * TIME_DURATION))
    // no route
    router.NoRoute(NoRouteResponse)
    // home
    var userController *controller.UserController
    router.Static("/web/assets", "./web/assets")
    router.StaticFS("/web/upload", http.Dir("/web/upload"))
    router.LoadHTMLGlob("web/*.tmpl")
...

分布式鏈路 Jaeger

引入 traceandtrace-go 實(shí)現(xiàn) Tracing middleware, 上報(bào)鏈路信息到 jaeger

import (
    "log"

    tracing "github.com/codeandcode0x/traceandtrace-go"
    "github.com/gin-gonic/gin"
)

// Tracing 中間件
func Tracing() gin.HandlerFunc {
    return func(c *gin.Context) {
        log.Println("..... tracing header1 ", c.Request.Header)
        // add tracing
        pctx, cancel := tracing.AddHttpTracing(
            "ticket-manager",
            c.Request.URL.String()+" "+c.Request.Method,
            c.Request.Header,
            map[string]string{
                "component":      "gin-server",
                "httpMethod":     c.Request.Method,
                "httpUrl":        c.Request.URL.String(),
                "proto":          c.Request.Proto,
                "peerService":    c.HandlerName(),
                "httpStatusCode": "200",
                "spanKind":       "server",
            })
        defer cancel()

        // deliver parent context
        c.Set("parentCtx", pctx)
        c.Next()
        return
    }
}

總結(jié)

  • gin 在 go web 上使用非常方便, 并且性能非常不錯(cuò)
  • 使用 gin 腳手架可以快速構(gòu)建開(kāi)發(fā)項(xiàng)目

另外分享一個(gè)基于腳手架開(kāi)發(fā)的 gRPC 代理網(wǎng)關(guān)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容