benchmark评测结果 显示,gin 秒杀其它的 web framework。
mkdir ginusage
cd ginusage
go mod init github.com/lijiaocn/ginusage
go get -u github.com/gin-gonic/gin@@v1.4.0
quickstart代码:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
gin API Examples 中给出 gin 的 api 用法,演示了如何处理 HTTP 请求,刚使用时主要关心下面的操作:
*. 怎样设置多个分组的路由 *. 怎样读取传入的参数
如果做 webserver 还要关心:
gin 的功能不少,而且比较灵活,这里只记录掌握后可以直接开发项目的基本的用法。
每个 Router 对应的 handler 函数类型为:
func(*gin.Context)
Router 分组方法如下,注意 v1.GET()、v1.POST() 在一个单独作用域里,这是 gin 的文档中给出的写法,无脑遵循这种写法了:
package main
import "github.com/gin-gonic/gin"
type A struct {
Value int
}
var a A
func SetA(c *gin.Context) {
c.JSON(200, a)
}
func GetA(c *gin.Context) {
c.JSON(200, a)
}
func main() {
router := gin.Default()
v1 := router.Group("/v1")
{
v1.GET("/a", GetA)
v1.POST("/a", SetA)
}
router.Run(":8080")
}
上面的例子中回应给客户端的是 json 字符串,c.JSON() 会自动将第二个参数序列化成 json 字符串后返回,数据绑定是反过来,将客户端提交的参数自动反序列成变量,见Model binding and validation。
如果客户端提交的是 json 字符串,被绑定的 struct 需要带有 json tag,设置了 binding:”required” 的是客户端必须提交的数据,如下:
type A struct {
Value int `json:"value" binding:"required"`
}
如果客户端提交的是表单(form)或者 xml 格式的数据,要设置对应的 form tag 和 xml tag,如下:
type A struct {
Value int `json:"value" form:"value" xml:"value" binding:"required"`
}
然后就可以在 Router 对应的 handler 中使用 Bind*
函数或者 ShouldBind*
函数直接将客户端发送的数据反序列化,前者在反序列化失败时直接设置返回的错误代码,后者需要自行设置:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type A struct {
Value int `json:"value" form:"value" xml:"value" binding:"required"`
}
var a A
func SetA(c *gin.Context) {
if err := c.ShouldBindJSON(&a); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(200, a)
}
func GetA(c *gin.Context) {
c.JSON(200, a)
}
func main() {
router := gin.Default()
v1 := router.Group("/v1")
{
v1.GET("/a", GetA)
v1.POST("/a", SetA)
}
router.Run(":8080")
}
https://github.com/gin-gonic/gin#custom-validators