Go的Http框架:gin

Gin其实就是一个简单的Http调用框架,内部帮我们集成了很多,我们只需要基于此框架完成业务的开发即可

下面是一个完整的示例,展示了 Gin 的简单性:

go 复制代码
package main

import (
  "net/http"

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

func main() {
  // Create a Gin router with default middleware (logger and recovery)
  r := gin.Default()
  
  // Define a simple GET endpoint
  r.GET("/ping", func(c *gin.Context) {
    // Return JSON response
    c.JSON(http.StatusOK, gin.H{
      "message": "pong",
    })
  })
  
  // Start server on port 8080 (default)
  // Server will listen on 0.0.0.0:8080 (localhost:8080 on Windows)
  r.Run()
}
  1. go run main.go
  2. 打开浏览器并访问http://localhost:8080/ping
  3. 应该看到:{"message":"pong"}
    路由路径的设置,遵循Restful风格(采用URL定位,HTTP描述操作):
go 复制代码
// 设置路由
router := gin.Default()
// 第一个参数是:路径; 第二个参数是:具体操作 func(c *gin.Context)
router.GET("/Get", getting)
router.POST("/Post", posting)
router.PUT("/Put", putting)
router.DELETE("/Delete", deleting)
// 默认启动的是 8080端口
router.Run()

1.路由分组

go 复制代码
// 两个路由组,都可以访问,大括号是为了保证规范
v1 := r.Group("/v1")
{
    // 通过 localhost:8080/v1/hello访问,以此类推
    v1.GET("/hello", sayHello)
    v1.GET("/world", sayWorld)
}
v2 := r.Group("/v2")
{
    v2.GET("/hello", sayHello)
    v2.GET("/world", sayWorld)
}
r.Run(":8080")

2.动态路由

go 复制代码
package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
)
func main() {
    r := gin.Default()
    r.GET("/user/:name", Handler1)
    err := r.Run("localhost:8081")
    if err != nil {
       return
    }
}

func Handler1(c *gin.Context) {
    fmt.Println(c)
    name := c.Param("name")
    c.String(http.StatusOK, "Hello %s", name)
}

访问:http://localhost:8081/user/ninesun

结果:Hello ninesun

  • 匹配users?name=xxx&role=xxx,role可选
go 复制代码
r.GET("/user/", Handler2)
func Handler2(c *gin.Context) {
    name := c.Query("name")
    role := c.DefaultQuery("role", "teacher")
    c.String(http.StatusOK, "%s is a %s", name, role)
}

访问:http://localhost:8081/user/?name=Tom\&role=student

结果:Tom is a student

3.获取POST参数

go 复制代码
r.POST("/form/", Handler3)
func Handler3(c *gin.Context) {
    username := c.PostForm("username")
    password := c.DefaultPostForm("password", "000000") // 可设置默认值
    c.JSON(http.StatusOK, gin.H{
       "username": username,
       "password": password,
    })
}

curl http://localhost:9999/form -X POST -d 'username=geektutu&password=1234'

结果:{"password":"1234","username":"geektutu"}

4.Query和POST混合参数

go 复制代码
r.POST("/posts/", Handler4)
func Handler4(c *gin.Context) {
    id := c.Query("id")
    page := c.DefaultQuery("page", "0")
    username := c.PostForm("username")
    password := c.DefaultPostForm("username", "000000") // 可设置默认值

    c.JSON(http.StatusOK, gin.H{
       "id":       id,
       "page":     page,
       "username": username,
       "password": password,
    })
}

$ curl "http://localhost:9999/posts?id=9876\&page=7" -X POST -d 'username=geektutu&password=1234'

{"id":"9876","page":"7","password":"1234","username":"geektutu"}

5.Map参数(字典参数)

go 复制代码
r.POST("/post", func(c *gin.Context) {
        ids := c.QueryMap("ids")
        names := c.PostFormMap("names")

        c.JSON(http.StatusOK, gin.H{
                "ids":   ids,
                "names": names,
        })
})

$ curl -g "http://localhost:9999/post?ids\[Jack\]=001\&ids\[Tom\]=002" -X POST -d 'names[a]=Sam&names[b]=David' {"ids":

{"Jack":"001","Tom":"002"},"names":{"a":"Sam","b":"David"}}

6.重定向(Redirect)

go 复制代码
r.GET("/redirect", func(c *gin.Context) {
    c.Redirect(http.StatusMovedPermanently, "/index")
})

r.GET("/goindex", func(c *gin.Context) {
        c.Request.URL.Path = "/"
        r.HandleContext(c)
})

7.大量路由实现

当我们的路由变得非常多的时候,那么建议遵循以下步骤:

  1. 建立routers包,将不同模块拆分到多个go文件
  2. 每个文件提供一个方法,该方法注册实现所有的路由
  3. 之后main方法在调用文件的方法实现注册

8.中间件(Middleware)

go 复制代码
// 作用于全局
r.Use(gin.Logger())
r.Use(gin.Recovery())

// 作用于单个路由
r.GET("/benchmark", MyBenchLogger(), benchEndpoint)

// 作用于某个组
authorized := r.Group("/")
authorized.Use(AuthRequired())
{
        authorized.POST("/login", loginEndpoint)
        authorized.POST("/submit", submitEndpoint)
}

如何自定义中间件呢?

go 复制代码
func Logger() gin.HandlerFunc {
        return func(c *gin.Context) {
                t := time.Now()
                // 给Context实例设置一个值
                c.Set("geektutu", "1111")
                // 请求前
                c.Next()
                // 请求后
                latency := time.Since(t)
                log.Print(latency)
        }
}
相关推荐
恣艺8 分钟前
用Go从零实现一个高性能KV存储引擎:B+Tree索引、WAL持久化、LRU缓存的工程实践
开发语言·数据库·redis·缓存·golang
geovindu13 小时前
go: Semaphore Pattern
开发语言·后端·设计模式·golang·企业级信号量模式
审判长烧鸡14 小时前
标准 HTTP API 签名鉴权 Header 完整规范
http·web
dusk_star16 小时前
go语言--笔记--封装、组合(继承)
笔记·golang
姚不倒18 小时前
Go 语言基础入门:从零到实战,一篇文章掌握核心语法
云原生·golang
00后程序员张19 小时前
HTTPS单向认证、双向认证、抓包原理与反抓包策略详解
网络协议·http·ios·小程序·https·uni-app·iphone
Soonyang Zhang19 小时前
nccl分析(三)——GPU-Initiated Networking(gin)数据发送过程分析
gin·nccl
June bug19 小时前
Failed to fetch+HTTP 422=Agent ID 不匹配
网络·网络协议·http
XMYX-020 小时前
33 - Go 文本模板 template:从入门到原理深挖
golang·正则表达式
minji...1 天前
Linux 网络基础之传输层协议TCP(九)从内核源码的角度打通系统与网络之间的关系,套接字多态的体现
linux·运维·服务器·网络·网络协议·tcp/ip·http