当前位置: 首页 > 工具软件 > example-app > 使用案例 >

从golang-gin-realworld-example-app项目学写httpapi (一)

凤自珍
2023-12-01

https://wangzitian0.github.io/2013/06/29/zero-to-one-1/

https://github.com/gothinkster/golang-gin-realworld-example-app

目录结构

golang-gin-realworld-example-app/
├── articles
│   ├── doc.go
│   ├── models.go
│   ├── routers.go
│   ├── serializers.go
│   └── validators.go
├── common
│   ├── database.go
│   ├── unit_test.go
│   └── utils.go
├── doc.go
├── main.go
├── scripts
│   ├── coverage.sh
│   └── gofmt.sh
├── users
│   ├── doc.go
│   ├── middlewares.go
│   ├── models.go
│   ├── routers.go
│   ├── serializers.go
│   ├── unit_test.go
│   └── validators.go
└── vendor
    └── vendor.json

https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/common/database.go

数据库

package common

import (
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
)

// 定义结构体Database
type Database struct {
    *gorm.DB
}

// 定义全局变量DB
var DB *gorm.DB

// 初始化数据库
func Init() *gorm.DB {
    // 连接数据库
    db, err := gorm.Open("sqlite3", "./../gorm.db")
    //db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8mb4&parseTime=True&loc=Local")

    if err != nil {
        fmt.Println("db err: ", err)
    }

    // 设置闲置的连接数
    db.DB().SetMaxIdleConns(10)
        // 设置最大打开的连接数
    db.DB().SetMaxOpenConns(100)

    // 启用Logger,显示详细日志
    db.LogMode(true)

    DB = db
    return DB
} 

// 函数,获取数据库连接,建立连接池
func GetDB() *gorm.DB {
    return DB
}              

https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/common/utils.go

工具集

package common

import (
    "fmt"
    "math/rand"
    "time"

    "github.com/dgrijalva/jwt-go"
    "gopkg.in/go-playground/validator.v8"

    "github.com/gin-gonic/gin/binding"
    "gopkg.in/gin-gonic/gin.v1"
)

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

// 函数 生成随机字符串
func RandString(n int) string {
    b := make([]rune, n)
    for i := range b {
        b[i] = letters[rand.Intn(len(letters))]
    }
    return string(b)
}

// Keep this two config private, it should not expose to open source
const NBSecretPassword = "A String Very Very Very Strong!!@##$!@#$"
const NBRandomPassword = "A String Very Very Very Niubilty!!@##$!@#4"

// 函数 生成请求头使用的jwt_token
func GenToken(id uint) string {
    jwt_token := jwt.New(jwt.GetSigningMethod("HS256"))
    // Set some claims
    jwt_token.Claims = jwt.MapClaims{
        "id":  id,
        "exp": time.Now().Add(time.Hour * 24).Unix(),
    }
    // Sign and get the complete encoded token as a string
    token, _ := jwt_token.SignedString([]byte(NBSecretPassword))
    return token
}

// 自定义错误类型
//  {"database": {"hello":"no such table", error: "not_exists"}}
type CommonError struct {
    Errors map[string]interface{} `json:"errors"`
}

// 一般错误处理
func NewError(key string, err error) CommonError {
    res := CommonError{}
    res.Errors = make(map[string]interface{})
    res.Errors[key] = err.Error()
    return res
}

// gin的validator错误处理
// https://github.com/go-playground/validator/blob/v9/_examples/translations/main.go
func NewValidatorError(err error) CommonError {
    res := CommonError{}
    res.Errors = make(map[string]interface{})
    errs := err.(validator.ValidationErrors)
    for _, v := range errs {
        // can translate each error one at a time.
        //fmt.Println("gg",v.NameNamespace)
        if v.Param != "" {
            res.Errors[v.Field] = fmt.Sprintf("{%v: %v}", v.Tag, v.Param)
        } else {
            res.Errors[v.Field] = fmt.Sprintf("{key: %v}", v.Tag)
        }

    }
    return res
}

// 变更gin-gonic的Bind函数,改变 c.MustBindWith() ->  c.ShouldBindWith().
func Bind(c *gin.Context, obj interface{}) error {
    b := binding.Default(c.Request.Method, c.ContentType())
    //return c.MustBindWith(obj, b)
    return c.ShouldBindWith(obj, b)
}
posted on 2018-11-15 19:11 北京涛子 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/liujitao79/p/9965528.html

 类似资料: