1. hello world
首先拉取gin開發框架
go get -u github.com /gin-gonic/gin
我們從入門的hello world入手看起gin是如何構建一個http服務器的
package main
import "github.com/gin-gonic/gin"
func main() {
engine := gin.Default()
engine.GET( "/ping" , func (ctx *gin.Context) {
ctx.JSON(200, gin.H{
"message" : "pong" ,
})
})
engine.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
可以看到gin的最簡單使用就需要三個步驟:
- 創建一個gin engine
- 注冊一個get方法的路由
- 開始監聽,默認為8080端口
2. Engine
在gin框架中,engine被定義成一個結構體,engine代表gin框架的一個結構體定義,其中包含了路由組、中間件、頁面渲染接口、框架配置設置等相關內容
默認的engine可以通過gin.Default進行創建,或者采用gin.New()同樣可以創建:
engine1 := gin.Default()
engine2 := gin.New()
gin.Default()和gin.New()的區別在於gin.Default()也是使用gin.New()創建engine實例,但是會默認使用Logger和Recovery中間件
Logger是負責進行打印並輸出日志的中間件,方便程序開發調試,就是我們在終端上看到的[GIN-debug]輸出
Recovery中間件的作用是如果程序執行中遇到了panic中斷了服務,則Recovery會恢復程序執行,並返回服務器內部500錯誤
3. 處理http請求
在創建engine實例中,包含很多方法可以處理不同類型的http請求
3.1 通用處理
engine中可以直接進行http請求的處理,在engine中使用Handle方法進行http請求的處理
Handle方法包含三個參數,具體為:
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes
- httpMethod:要處理的http請求類型,GET/POST等
- relativePath:要解析的接口
- handlers:處理對應的請求的代碼的定義
示例,Handle處理GET請求:
func main() {
engine := gin.Default()
// http://localhost:8080/hello?name=james
engine.Handle("GET", "/hello", func(ctx *gin.Context) {
fmt.Println(ctx.FullPath())
name := ctx.DefaultQuery("name", "pangjiping") // 第二個參數是默認值
ctx.Writer.Write([]byte("hello " + name))
})
engine.Run()
}
3.2 分類處理
除了engine中包含的通用處理方法外,engine還可以按照類型直接進行解析
engine中包含了get/post/delete等請求對應的方法
3.2.1 engine.GET()處理GET請求
engine中包含了GET請求的處理方法
context.DefaultQuery:用來解析GET請求攜帶的參數,如果沒有傳入參數則使用默認值,還可以使用context.Query方法來獲取GET請求攜帶的參數
// get
// http://localhost:8080/test01?username=james
engine.GET( "/test01" , func (ctx *gin.Context) {
fmt.Println(ctx.FullPath())
username := ctx.DefaultQuery( "username" , "pjp" )
ctx.Writer.Write([]byte(username))
})
3.2.2 engine.POST()處理POST請求
可以使用很多種方式來解析post表單的數據,這和我們請求的參數類型有關系
// post
// http://localhost:8080/login
engine.POST( "/login" , func (ctx *gin.Context) {
fmt.Println(ctx.FullPath())
username, ok := ctx.GetPostForm("username")
if ok {
fmt.Println(username)
}
password, ok := ctx.GetPostForm("password")
if ok {
fmt.Println(password)
}
ctx.Writer.Write([]byte("hello"))
})
3.2.3 engine.DELETE()處理DELETE請求
// delete
// http://localhost/user/:id
engine.DELETE("/user/:id" , func (ctx *gin.Context) {
userID := ctx.Param("id")
fmt.Println(userID)
ctx.Writer.Write([]byte("goodbye " + userID))
})
4. Run()
engine.Run()其實底層就是調用了net/http標准庫的ListenAndServer()函數
// Run attaches the router to a http.Server and starts listening and serving HTTP requests.
// It is a shortcut for http.ListenAndServe(addr, router)
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) Run(addr ...string) (err error) {
defer func() { debugPrintError(err) }()
if engine.isUnsafeTrustedProxies() {
debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" +
"Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
}
address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
err = http.ListenAndServe(address, engine.Handler())
return
}