Go框架之Gin应用到原理源码
基本概览:
目前 golang使用最广泛的Web 微框架之一。具有高性能的优点,基于 httprouter,它提供了类似martini但更好性能(路由性能约快40倍)的API服务。
本文将从基本应用快速上手到中间件集成,自定义中间件和Gin + router 原理源码解读
官方地址:https://github.com/gin-gonic/gin
中文API:文档 | Gin Web Framework
案例:
go get -u github.com/gin-gonic/gin
下载依赖
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default() //拿到一个 *gin.Engine
r.GET("ping", func(ctx *gin.Context) { //获取GET请求
ctx.JSON(200, gin.H{
"msg": "pong",
})
})
r.Run() //开启服务 0.0.0.0:8080
}
addRoute
gin. Default 还有gin. New
关系:default 内部也是调用的 New 但是会默认加上 Logger 和 Recovery中间件
HTTP请求 及 Handle
GET POST
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)
func someGet(c *gin.Context) {
fmt.Println("someGet")
c.Writer.WriteString("this is someGet()")
}
func somePost(c *gin.Context) {
fmt.Println("somePost")
c.Writer.WriteString("this is somePost()")
}
func main() {
r := gin.Default() //拿到一个 *gin.Engine
r.GET("ping", func(ctx *gin.Context) { //获取GET请求
ctx.JSON(200, gin.H{
"msg": "pong",
})
})
r.GET("/someGet", someGet)
r.POST("/somePost", somePost)
r.Run() //开启服务 0.0.0.0:8080
}
请求参数处理:
Get请求
关键方法
c.Query(“key”) (.var 会自动填充前面)
c.DefaultQuery(“key”,“xxoo”) 没有key 会给一个默认值
Post请求
关键方法
c.PostForm()
c.DefaultPostFrom()
代码实现:
func getKey(c *gin.Context) {
s := c.Query("name")
ss := c.DefaultQuery("age", "xxoo")
c.String(200, "this is getKey() 获取到key=%s %s", s, ss)
}
func postVal(c *gin.Context) {
s := c.PostForm("name")
ss := c.DefaultPostForm("age", "xxoo")
// c.HTML(200, "welcome.html", gin.H{
// "name": s,
// "age": ss,
// })
c.String(200, "this is postVal() 获取到key=%s %s", s, ss)
}
func main (){
r := gin.Default()
r.GET("/getKey", getKey)
r.POST("/postVal", postVal)
...
}
RestFul风格路径参数
使用c.Param(“key”)方法
e.GET(“/hello/:username”,testPathParam)
e.GET(“/hello/:username/:age”,testPathParam) 可多个
func getParam(c *gin.Context) {
usename := c.Param("usename")
age := c.Param("age")
c.String(200, "this is getKey() 获取到key=%s %s", usename, age)
}
main方法中 :
//r.GET("/getParam/:usename", getParam)
r.GET("/getParam/:usename/:age", getParam)
http://localhost:8080/getParam/xxx/18
引入模板引擎 HTML
query.html
然后 e.LoadHTMLGlob(“templates/*”)
func postVal(c *gin.Context) {
s := c.PostForm("name")
ss := c.DefaultPostForm("age", "xxoo")
c.HTML(200, "welcome.html", gin.H{
"name": s,
"age": ss,
})
//c.String(200, "this is postVal() 获取到key=%s %s", s, ss)
}
并且在main方法中
r.LoadHTMLGlob("src/gin/01/templates/*")
页面get与post都有
像百度搜索 goSearch跳到 搜索页面 结果分页的?过来
//比如:https://www.baidu.com/s?wd=xxoo页面的表单
func search(c *gin.Context) {
page := c.DefaultQuery("page", "0")
key := c.PostForm("key")
age := c.PostForm("age")
hobby := c.PostFormArray("hobby")
c.String(200, "this is search() 获取到 page:%s key:%s age:%s hobby:%s", page, key, age, hobby)
}
main方法中
r.POST("/search", search)
数据绑定Form表单
c.ShouldBind(&user)
func toRegister(c *gin.Context) {
c.HTML(200, "register.html", nil)
}
func register(c *gin.Context) {
var user model.User
c.ShouldBind(&user)
c.String(200, "获取到 %s", user)
}
func main (){
r := gin.Default()
r.GET("/toRegister", toRegister)
r.POST("/register", register)
r.Run() //开启服务 0.0.0.0:8080
}
type User struct {
UserName string `form:"name"`//如果页面表单的字段名与结构体的一致 可以省略此
Password string `form:"password"`
Hobby []string `form:"hobby"`
}
<form action="/register" method="post">
<input name="name"><br/>
<input name="password"><br/>
<input type="checkbox" name="hobby" value="GoLang" >GoLang
<input type="checkbox" name="hobby" value="Java" >Java
<input type="checkbox" name="hobby" value="C++" >C++