基于 gin框架搭建入门项目

go mod init gin-ranking
go: creating new go.mod: module gin-ranking
go: to add module requirements and sums:
        go mod tidy

下载gin框架

cmd窗口中执行命令:

go get -u github.com/gin-gonic/gin
package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	r := gin.Default()
	r.GET("/hello", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "hello world!")
	})

	r.POST("/user/list", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "user list!")
	})

	r.PUT("/user/add", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "user add !")
	})

	r.DELETE("/user/delete", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "user delete!")
	})

	r.Run(":9999")
}

运行

go run main.go

基于 gin框架搭建入门项目_第1张图片

也可以支持分组

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	r := gin.Default()
	r.GET("/hello", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "hello world!")
	})

	user := r.Group("/user")
	{
		user.POST("/list", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user list!")
		})

		user.PUT("/add", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user add !")
		})

		user.DELETE("/delete", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user delete!")
		})

	}

	r.Run(":9999")
}

如果路由有很多个都放在main.go文件中不太好

基于 gin框架搭建入门项目_第2张图片

封装Json 返回统一格式

基于 gin框架搭建入门项目_第3张图片

main.go

package main

import "gin-ranking/router"

func main() {
	r := router.Router()
	r.Run(":9999")
}

router.go

package router

import (
	"gin-ranking/controllers"
	"github.com/gin-gonic/gin"
	"net/http"
)

func Router() *gin.Engine {
	r := gin.Default()

	user := r.Group("/user")
	{
		user.GET("/info", controllers.GetUserInfo)

		user.POST("/list", controllers.GetList)

		user.PUT("/add", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user add !")
		})

		user.DELETE("/delete", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user delete!")
		})

	}
	return r

}

user.go

package controllers

import "github.com/gin-gonic/gin"

func GetUserInfo(c *gin.Context) {
	ReturnSuccess(c, 0, "success", "user info", 1)
}

func GetList(c *gin.Context) {
	ReturnError(c, 404, "没有相关信息")
}

common.go

package controllers

import "github.com/gin-gonic/gin"

type JsonStruct struct {
	Code  int         `json:"code"`
	Msg   interface{} `json:"msg"`
	Data  interface{} `json:"data"`
	Count int64       `json:"count"`
}

type JsonErrStruct struct {
	Code int         `json:"code"`
	Msg  interface{} `json:"msg"`
}

func ReturnSuccess(c *gin.Context, code int, msg interface{}, data interface{}, count int64) {
	json := &JsonStruct{
		Code: code, Msg: msg, Data: data, Count: count,
	}
	c.JSON(200, json)
}

func ReturnError(c *gin.Context, code int, msg interface{}) {
	json := &JsonErrStruct{Code: code, Msg: msg}
	c.JSON(200, json)
}

127.0.0.1:9999/user/info
{
    "code": 0,
    "msg": "success",
    "data": "user info",
    "count": 1
}
127.0.0.1:9999/user/list

{
    "code": 404,
    "msg": "没有相关信息"
}

基于 gin框架搭建入门项目_第4张图片

但是有个问题,如果在别的包中调用同一个方法就会报错,可以借用结构体

router.go

package router

import (
	"gin-ranking/controllers"
	"github.com/gin-gonic/gin"
	"net/http"
)

func Router() *gin.Engine {
	r := gin.Default()

	user := r.Group("/user")
	{
		user.GET("/info", controllers.UserController{}.GetUserInfo)

		user.POST("/list", controllers.UserController{}.GetList)

		user.PUT("/add", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user add !")
		})

		user.DELETE("/delete", func(ctx *gin.Context) {
			ctx.String(http.StatusOK, "user delete!")
		})

	}

	order := r.Group("/order")
	{
		order.POST("/list", controllers.OrderController{}.GetList)
	}
	return r

}

order.go

package controllers

import "github.com/gin-gonic/gin"

type OrderController struct {
}

func (o OrderController) GetList(c *gin.Context) {
	ReturnError(c, 404, "没有相关信息 order")
}

user.go

package controllers

import "github.com/gin-gonic/gin"

type UserController struct {
}

func (u UserController) GetUserInfo(c *gin.Context) {
	ReturnSuccess(c, 0, "success", "user info", 1)
}

func (u UserController) GetList(c *gin.Context) {
	ReturnError(c, 404, "没有相关信息")
}

获取请求参数并和struct结构体绑定

1.get 请求 携带路由参数
基于 gin框架搭建入门项目_第5张图片

基于 gin框架搭建入门项目_第6张图片
基于 gin框架搭建入门项目_第7张图片

Post传递表单类型的参数
基于 gin框架搭建入门项目_第8张图片
基于 gin框架搭建入门项目_第9张图片

传递json类型的数据
基于 gin框架搭建入门项目_第10张图片
通过定义结构体的方式传递
基于 gin框架搭建入门项目_第11张图片

自定义Logger中间件实现日志收集

根目录下新建 runtime/log 目录用以保存生成的日志

根目录下新建pkg/logger/logger.go

package logger

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"io"
	"net/http"
	"os"
	"path"
	"runtime/debug"
	"time"
)

func init() {
	// 设置日志格式为json格式
	logrus.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	logrus.SetReportCaller(false)
}

func Write(msg string, filename string) {
	setOutPutFile(logrus.InfoLevel, filename)
	logrus.Info(msg)
}

func Debug(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.DebugLevel, "debug")
	logrus.WithFields(fields).Debug(args)
}

func Info(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.InfoLevel, "info")
	logrus.WithFields(fields).Info(args)
}

func Warn(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.WarnLevel, "warn")
	logrus.WithFields(fields).Warn(args)
}

func Fatal(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.FatalLevel, "fatal")
	logrus.WithFields(fields).Fatal(args)
}

func Error(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.ErrorLevel, "error")
	logrus.WithFields(fields).Error(args)
}

func Panic(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.PanicLevel, "panic")
	logrus.WithFields(fields).Panic(args)
}

func Trace(fields logrus.Fields, args ...interface{}) {
	setOutPutFile(logrus.TraceLevel, "trace")
	logrus.WithFields(fields).Trace(args)
}

func setOutPutFile(level logrus.Level, logName string) {
	if _, err := os.Stat("./runtime/log"); os.IsNotExist(err) {
		err = os.MkdirAll("./runtime/log", 0777)
		if err != nil {
			panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", err))
		}
	}

	timeStr := time.Now().Format("2006-01-02")
	fileName := path.Join("./runtime/log", logName+"_"+timeStr+".log")

	var err error
	os.Stderr, err = os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		fmt.Println("open log file err", err)
	}
	logrus.SetOutput(os.Stderr)
	logrus.SetLevel(level)
	return
}

func LoggerToFile() gin.LoggerConfig {

	if _, err := os.Stat("./runtime/log"); os.IsNotExist(err) {
		err = os.MkdirAll("./runtime/log", 0777)
		if err != nil {
			panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", err))
		}
	}

	timeStr := time.Now().Format("2006-01-02")
	fileName := path.Join("./runtime/log", "success_"+timeStr+".log")

	os.Stderr, _ = os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)

	var conf = gin.LoggerConfig{
		Formatter: func(param gin.LogFormatterParams) string {
			return fmt.Sprintf("%s - %s \"%s %s %s %d %s \"%s\" %s\"\n",
				param.TimeStamp.Format("2006-01-02 15:04:05"),
				param.ClientIP,
				param.Method,
				param.Path,
				param.Request.Proto,
				param.StatusCode,
				param.Latency,
				param.Request.UserAgent(),
				param.ErrorMessage,
			)
		},
		Output: io.MultiWriter(os.Stdout, os.Stderr),
	}

	return conf
}

func Recover(c *gin.Context) {
	defer func() {
		if err := recover(); err != nil {
			if _, errDir := os.Stat("./runtime/log"); os.IsNotExist(errDir) {
				errDir = os.MkdirAll("./runtime/log", 0777)
				if errDir != nil {
					panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", errDir))
				}
			}

			timeStr := time.Now().Format("2006-01-02")
			fileName := path.Join("./runtime/log", "error_"+timeStr+".log")

			f, errFile := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
			if errFile != nil {
				fmt.Println(errFile)
			}
			timeFileStr := time.Now().Format("2006-01-02 15:04:05")
			f.WriteString("panic error time:" + timeFileStr + "\n")
			f.WriteString(fmt.Sprintf("%v", err) + "\n")
			f.WriteString("stacktrace from panic:" + string(debug.Stack()) + "\n")
			f.Close()
			c.JSON(http.StatusOK, gin.H{
				"code": 500,
				"msg":  fmt.Sprintf("%v", err),
			})
			//终止后续接口调用,不加的话recover到异常后,还会继续执行接口里后续代码
			c.Abort()
		}
	}()
	c.Next()
}

直接在方法中调用
基于 gin框架搭建入门项目_第12张图片
基于 gin框架搭建入门项目_第13张图片

引入Gorm

根目录新建config/db.go
在这里插入图片描述
根目录新建dao/dao.go
基于 gin框架搭建入门项目_第14张图片

package dao

import (
	"gin-ranking/config"
	"gin-ranking/pkg/logger"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"time"
)

var (
	Db  *gorm.DB
	err error
)

func init() {
	Db, err = gorm.Open("mysql", config.Mysqldb)
	if err != nil {
		logger.Error(map[string]interface{}{"mysql connect error": err.Error()})
	}
	if Db.Error != nil {
		logger.Error(map[string]interface{}{"database error": Db.Error})
	}

	// ----------------------- 连接池设置 -----------------------
	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
	Db.DB().SetMaxIdleConns(10)

	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	Db.DB().SetMaxOpenConns(100)

	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	Db.DB().SetConnMaxLifetime(time.Hour)
}

新建models/user 测试
基于 gin框架搭建入门项目_第15张图片
在请求方法中直接调用
基于 gin框架搭建入门项目_第16张图片
基于 gin框架搭建入门项目_第17张图片

基于 gin框架搭建入门项目_第18张图片

新增用户
基于 gin框架搭建入门项目_第19张图片
基于 gin框架搭建入门项目_第20张图片
基于 gin框架搭建入门项目_第21张图片
基于 gin框架搭建入门项目_第22张图片

更新数据
基于 gin框架搭建入门项目_第23张图片

基于 gin框架搭建入门项目_第24张图片

基于 gin框架搭建入门项目_第25张图片
基于 gin框架搭建入门项目_第26张图片

删除
基于 gin框架搭建入门项目_第27张图片
基于 gin框架搭建入门项目_第28张图片
在这里插入图片描述
基于 gin框架搭建入门项目_第29张图片

查询多条数据
models

func GerUserListTest() ([]User, error) {
	var users []User
	err := dao.Db.Where("id, 3).Find(&users).Error
	return users, err
}

controllers

func (u UserController) GerUserListTest(c *gin.Context) {
	users, err := models.GerUserListTest()
	if err != nil {
		ReturnError(c, 4004, "删除失败")
		return
	}
	ReturnSuccess(c, 0, "删除成功", users, 1)

}

在这里插入图片描述

你可能感兴趣的:(Go,gin,iphone,ios)