gin框架的简单使用

gin框架是基于golang语言的web框架。如果用gin实现服务,有下述的场景需求,那么可以继续阅览:

  • 服务针对不同的路由,有不同的验证规则。比如服务对应PC管理端和移动端,分别有不同的验证规则,涉及路由组、中间件拦截验证;
  • 请求记录、操作日志按照时间每天记录到文件中。涉及中间件日志操作;
  • 跨域问题,涉及中间件跨域;
  • API的使用,涉及常用的POST,PUT,GET,DELETE。

代码示意:

package main
import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"time"
	"github.com/gin-gonic/gin"
)
type User struct {
	Name string `json:"name"`
	Age int `json:"age"`
}
func main(){
	gin.SetMode(gin.DebugMode)
	router := gin.New()
	router.Use(LoggerByTime())//中间件:日志
	router.Use(gin.Recovery())
	router.Use(Cors())//中间件:跨域

	api:=router.Group("/pc").Use(AuthRequiredPc)//pc开头的路由中间件:验证
	{
		api.POST("/add", func(c *gin.Context) {//参数方式:body
			var (
				user User
				rtn Rtn
				)
			err := c.ShouldBindJSON(&user)
			if err != nil {
				fmt.Fprintln(GetLogFileName(), "Add:"+err.Error())
				rtn.R = 0
				rtn.Err = err.Error()
				c.JSON(http.StatusInternalServerError,rtn)
				panic(err)
				return
			}
			fmt.Fprintln(GetLogFileName(), "添加了一个用户,名="+user.Name+",年龄="+strconv.Itoa(user.Age))
			rtn.R = 1
			c.JSON(http.StatusOK,rtn)
		})
		api.PUT("/edit", func(c *gin.Context) {//参数方式:body
			var (
				user User
				rtn Rtn
			)
			err := c.ShouldBindJSON(&user)
			if err != nil {
				fmt.Fprintln(GetLogFileName(), "Edit:"+err.Error())
				rtn.R = 0
				rtn.Err = err.Error()
				c.JSON(http.StatusInternalServerError,rtn)
				panic(err)
				return
			}
			fmt.Fprintln(GetLogFileName(), "编辑了用户,名="+user.Name+",年龄="+strconv.Itoa(user.Age))
			rtn.R = 1
			c.JSON(http.StatusOK,rtn)
		})
		api.DELETE("/del", func(c *gin.Context) {//参数方式:post form
			var rtn Rtn
			name := c.PostForm("name")
			fmt.Fprintln(GetLogFileName(), "删除用户名="+name)
			rtn.R = 1
			c.JSON(http.StatusOK,rtn)
		})
	}
	apiOut:=router.Group("/mobile").Use(AuthRequiredMobile)//mobile开头的路由中间件:验证
	{
		apiOut.GET("/detail", func(c *gin.Context) {//参数方式:query
			var rtn Rtn
			name := c.Query("name")
			fmt.Fprintln(GetLogFileName(), "详情:"+"该用户名="+name)
			rtn.R = 1
			c.JSON(http.StatusOK,rtn)
		})
	}

	router.Run(":8888")
}

//中间件:日志。参考gin自带的日志中间件实现日志按照天存储,详见gin/logger.go部分
func GetLogFileName()*os.File{
	filename:=fmt.Sprintf("./%s",time.Now().Format("20060102"))
	fileObj,_ := os.OpenFile(filename,os.O_RDWR|os.O_CREATE|os.O_APPEND,0777)
	return fileObj
}
type logger struct{
	Time string// Time shows the time after the server returns a response.
	StatusCode int// StatusCode is HTTP response code.
	Latency string// Latency is how much time the server cost to process a certain request.
	ClientIP string// ClientIP equals Context's ClientIP method.
	Method string// Method is the HTTP method given to the request.
	Path string// Path is a path the client requests.
}
func LoggerByTime() gin.HandlerFunc {
	return func(c *gin.Context) {
		// Start timer
		start := time.Now()
		path := c.Request.URL.Path
		raw := c.Request.URL.RawQuery
		// Process request
		c.Next()
		param := logger{}
		// Stop timer
		param.Time = time.Now().Format("2006-01-02 15:04:05")
		param.Latency = fmt.Sprintf("%dms",time.Now().Sub(start).Nanoseconds()/1e6)
		param.ClientIP = c.ClientIP()
		param.Method = c.Request.Method
		param.StatusCode = c.Writer.Status()
		if raw != "" {
			path = path + "?" + raw
		}
		param.Path = path
		paramStr, _ := json.Marshal(param)
		fmt.Fprintln(GetLogFileName(), string(paramStr))
	}
}

//中间件:跨域。可根据自己需求进行调整
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		origin := c.Request.Header.Get("Origin")
		if origin != "" {
			c.Header("Access-Control-Allow-Origin", "*")
			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
			c.Header("Access-Control-Allow-Headers", "Origin,Authorization,Content-Length,Content-Type,Date,DataField")
			c.Header("Access-Control-Max-Age", "3600")
			c.Header("Access-Control-Allow-Credentials", "true")
		}
		if method == "OPTIONS" {
			c.JSON(http.StatusOK, "Options Request!")
		}
		c.Next()
	}
}

//中间件:拦截校验
//拦截校验
type Rtn struct {
	R int    `json:"r"`
	Data interface{} `json:"data"`
	Err  string `json:"err"`
}
func AuthRequiredPc(c *gin.Context){
	var rtn Rtn
	var err error
	authorization := c.Request.Header.Get("Authorization")
	if authorization != "pc"{
		rtn.Data=0
		err = errors.New("authen error!")
		fmt.Fprintln(GetLogFileName(), "AuthRequired:"+err.Error())
		rtn.Err = err.Error()
		c.JSON(http.StatusInternalServerError,rtn)
		panic(err)
		return
	}
}
func AuthRequiredMobile(c *gin.Context){
	var rtn Rtn
	var err error
	authorization := c.Request.Header.Get("Authorization")
	if authorization != "mobile"{
		rtn.Data=0
		err = errors.New("authen error!")
		fmt.Fprintln(GetLogFileName(), "AuthRequired:"+err.Error())
		rtn.Err = err.Error()
		c.JSON(http.StatusInternalServerError,rtn)
		panic(err)
		return
	}
}

 

你可能感兴趣的:(go)