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()
}
- go run main.go
- 打开浏览器并访问http://localhost:8080/ping
- 应该看到:{"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.大量路由实现
当我们的路由变得非常多的时候,那么建议遵循以下步骤:
- 建立routers包,将不同模块拆分到多个go文件
- 每个文件提供一个方法,该方法注册实现所有的路由
- 之后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)
}
}