弑
弑君者
V1
2023/01/21阅读:32主题:默认主题
Gin 入门
安装
-
快速入门
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func pong(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
}
func main() {
// 实例化一个gin的server对象
// Creates a gin router with default middleware:
// logger and recovery (crash-free) middleware
r := gin.Default()
// 定义一个接口
r.GET("/ping", pong)
// 监听8083端口
r.Run(":8083")
}
代码很简单,这样就启动了服务

-
使用get、post、put等方法
func main() {
// Creates a gin router with default middleware:
// logger and recovery (crash-free) middleware
router := gin.Default()
router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)
// By default it serves on :8080 unless a
// PORT environment variable was defined.
router.Run()
// router.Run(":3000") for a hard coded port
}
-
url和路由分组
路由分组: 每一个服务下面都有很多的接口,所以需要给每个服务建立一个分组。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
goodsGroup := router.Group("/goods")
{
goodsGroup.GET("", goodsList)
goodsGroup.GET("/:id/:action/add", goodsDetail) //获取商品id为1的详细信息 模式
goodsGroup.POST("", createGoods)
}
router.Run(":8083")
}
func createGoods(c *gin.Context) {
}
func goodsDetail(c *gin.Context) {
// 获取参数
id := c.Param("id")
action := c.Param("action")
c.JSON(http.StatusOK, gin.H{
"id": id,
"action": action,
})
}
func goodsList(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"name": "goodsList",
})
}
获取url参数
func main() {
router := gin.Default()
// This handler will match /user/john but will not match /user/ or /user
router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, "Hello %s", name)
})
// However, this one will match /user/john/ and also /user/john/send
// If no other routers match /user/john, it will redirect to /user/john/
router.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
})
// For each matched request Context will hold the route definition
router.POST("/user/:name/*action", func(c *gin.Context) {
b := c.FullPath() == "/user/:name/*action" // true
c.String(http.StatusOK, "%t", b)
})
// This handler will add a new router for /user/groups.
// Exact routes are resolved before param routes, regardless of the order they were defined.
// Routes starting with /user/groups are never interpreted as /user/:name/... routes
router.GET("/user/groups", func(c *gin.Context) {
c.String(http.StatusOK, "The available groups are [...]")
})
router.Run(":8080")
}
从get和post 方法中获取参数
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/welcome", welcome)
router.POST("/form_post", formPost)
router.POST("/post", getPost)
router.Run(":8083")
}
func getPost(c *gin.Context) {
id := c.Query("id")
page := c.DefaultQuery("page", "0")
name := c.PostForm("name")
message := c.DefaultPostForm("message", "信息")
c.JSON(http.StatusOK, gin.H{
"id": id,
"page": page,
"name": name,
"message": message,
})
}
func formPost(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
c.JSON(http.StatusOK, gin.H{
"message": message,
"nick": nick,
})
}
func welcome(c *gin.Context) {
firstName := c.DefaultQuery("firstname", "bobby")
lastName := c.DefaultQuery("lastname", "imooc")
c.JSON(http.StatusOK, gin.H{
"first_name": firstName,
"last_name": lastName,
})
}
-
自定义gin中间件
什么是中间件
这个和koa还有egg的中间件类似
实现一个打log的中间件
func MyLogger() gin.HandlerFunc {
// 返回一个函数就可以了
return func(c *gin.Context) {
t := time.Now()
c.Set("example", "123456")
// 让原本应该执行的逻辑继续执行
c.Next()
// 执行完以后,然后再执行之类的逻辑
end := time.Since(t)
fmt.Printf("耗时:%v\n", end)
status := c.Writer.Status()
fmt.Println("状态", status)
}
}
gin 中间件原理
使用切片,如果调用了next,就会调用切片的下一个函数,这里使用了一个index索引

-
gin 退出
package main
import (
"context"
"errors"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
time.Sleep(5 * time.Second)
c.String(http.StatusOK, "Welcome Gin Server")
})
srv := &http.Server{
Addr: ":8080",
Handler: router,
}
// Initializing the server in a goroutine so that
// it won't block the graceful shutdown handling below
// 在协程中使用,
go func() {
if err := srv.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
log.Printf("listen: %s\n", err)
}
}()
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal, 2)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
// 准备接受信号
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
// The context is used to inform the server it has 5 seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
}
作者介绍
弑
弑君者
V1