这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
选择框架需要框架的性能与稳定性
go get -u github.com/gin-gonic/gin
import "github.com/gin-gonic/gin"
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default() //返回默认的路由引擎
r.GET("/hello", sayHello)
r.Run(":9090")
}
func sayHello(context *gin.Context) {
context.JSON(200, gin.H{
"message": "hello",
})
}
- Restful风格
- 路由
r.GET("/user/find/:id", func(ctx *gin.Context) {
ctx.JSON(200, ctx.Param("id"))
})
r.GET("/user/*path", func(ctx *gin.Context) {
ctx.JSON(200, ctx.Param("path")) //返回以user开头的路径
})
v1 := r.Group("v1")
{
v1.GET("find", func(ctx *gin.Context) {
ctx.JSON(200, "v1-find")
})
v1.GET("save", func(ctx *gin.Context) {
ctx.JSON(200, "v1-save")
})
}
- 参数
r.GET("/user/save", func(ctx *gin.Context) {
id := ctx.Query("id")
name := ctx.Query("name")
addr, isExist := ctx.GetQuery("address") // 默认值 query := ctx.DefaultQuery("address", "beijing")
ctx.JSON(200, gin.H{
"id": id,
"name": name,
"address": addr,
"ok": isExist,
})
})
package main
import (
"github.com/gin-gonic/gin"
"log"
)
type User struct {
Name string `form:"name"`
Id int `form:"id"`
}
func main() {
r := gin.Default()
r.GET("/user/save", func(ctx *gin.Context) {
var user User
err := ctx.ShouldBindQuery(&user)
if err != nil {
log.Println(err)
}
ctx.JSON(200, user)
})
r.Run()
}
r.GET("/user/save", func(ctx *gin.Context) {
address := ctx.QueryArray("address")
ctx.JSON(200, address)
})
r.GET("/user/save", func(ctx *gin.Context) {
address := ctx.QueryMap("address")
ctx.JSON(200, address)
})
- post请求参数
r.POST("/user/save", func(ctx *gin.Context) {
//id := ctx.PostForm("id")
//name := ctx.PostForm("name")
//address := ctx.PostFormArray("address")
var user User
ctx.ShouldBind(&user)
ctx.JSON(200, user)
})
json传参使用结构体进行获取,与form无关,json获取参数时会将名称的第一个大写字母转化为小写,或者使用
`json:"id"`
`json:"name"`
`json:addresses`
r.LoadHTMLFiles("./template/index.html") //加载模板
r.GET("/html", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "index.html", gin.H{
"title": "lishuo",
})
})
- cookie
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/cookie", func(c *gin.Context) {
cookie, err := c.Cookie("gin_cookie")
if err != nil {
cookie = "NotSet"
c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
}
fmt.Printf("Cookie value: %s \n", cookie)
})
router.Run()
}
- session使用
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("mysession", store))
r.GET("/hello", func(c *gin.Context) {
session := sessions.Default(c)
if session.Get("hello") != "world" {
session.Set("hello", "world")
session.Save()
}
c.JSON(200, gin.H{"hello": session.Get("hello")})
})
r.Run(":8000")
}
- 中间件
指可以拦截http请求-响应生命周期的特殊函数,
func main() {
// 新建一个没有任何默认中间件的路由
r := gin.New()
// 全局中间件
// Logger 中间件将日志写入 gin.DefaultWriter,即使你将 GIN_MODE 设置为 release。
// By default gin.DefaultWriter = os.Stdout
r.Use(gin.Logger())
// Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500。
r.Use(gin.Recovery())
// 你可以为每个路由添加任意数量的中间件。
r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
// 认证路由组
// authorized := r.Group("/", AuthRequired())
// 和使用以下两行代码的效果完全一样:
authorized := r.Group("/")
// 路由组中间件! 在此例中,我们在 "authorized" 路由组中使用自定义创建的
// AuthRequired() 中间件
authorized.Use(AuthRequired())
{
authorized.POST("/login", loginEndpoint)
authorized.POST("/submit", submitEndpoint)
authorized.POST("/read", readEndpoint)
// 嵌套路由组
testing := authorized.Group("testing")
testing.GET("/analytics", analyticsEndpoint)
}
// 监听并在 0.0.0.0:8080 上启动服务
r.Run(":8080")
}
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
// 设置 example 变量
c.Set("example", "12345")
// 请求前
c.Next()
// 请求后
latency := time.Since(t)
log.Print(latency)
// 获取发送的 status
status := c.Writer.Status()
log.Println(status)
}
}
func main() {
r := gin.New()
r.Use(Logger())
r.GET("/test", func(c *gin.Context) {
example := c.MustGet("example").(string)
// 打印:"12345"
log.Println(example)
})
// 监听并在 0.0.0.0:8080 上启动服务
r.Run(":8080")
}