
2024年在線市場平臺的11大最佳支付解決方案
之后使用go mod download
命令下載。
或者在項目目錄中直接運行?go get github.com/gin-gonic/gin@v1.7.4
?命令,也會下載gin包,并且會自動添加到go.mod 文件中。
新建一個server.go 文件,寫入以下代碼
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"Msg":"Hello World",
})
})
r.Run(":8080")
}
代碼很簡單,運行go run server.go
?則會在8080端口啟動一個http服務,使用瀏覽器訪問?http://127.0.0.1:8080/
?則會返回json的數據
{
Msg: "Hello world"
}
上面代碼中,使用gin.Default()
創建一個默認的gin應用,這個應用底層初始化了很多設置,這里就先不深入探索了。
這里就注冊了一個路由,/
,它的處理由一個匿名函數來處理, gin 中的GET方法的定義為
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
handler 為處理方法,該方法的定義為
type HandlerFunc func(*Context)
所以這里需要一個參數為(*Context) 的函數,上面的代碼中使用
func(c *gin.Context) {
c.JSON(200, gin.H{
"Msg":"Hello World",
})
}
這個匿名函數來處理 /
的GET請求。
這里還可以定義POST、DELETE、PUT 等方法,這樣可以很方便的編寫restful 風格的API,
r.POST("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"Msg":"Hello world POST",
})
})
默認的404處理,會打印 404 not found,更多的時候,我們想自定義404頁面的處理,這時可以通過設置r.NoRoute
?方法來實現
r.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{
"Msg": "The page not found",
})
})
這時在訪問一個不存在的路由時會展示自定義的內容。
很多時候,我們是有這樣的需求,訪問的路由前面都有統一的前綴,如/api/v1
?, 或者/user
?,當然可以在定義路由的時候都統一寫上前綴,但是這種方式,如果后期修改了前綴將要改好多地方。這里可以使用路由組的概念。
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"Msg": "Hello world",
})
})
apiv1 := r.Group("/api/v1")
{
apiv1.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"msg": "hello api v1"})
})
}
r.Run(":8080")
}
以上代碼,定義了一個路由組,/api/v1
??, 之后又會在該路由組下定義相應的處理方法,這里區分?http://127.0.0.1:8080/
?這個url 返回?"Msg": "Hello world"
, ?/api/v1/
?這個路由返回?"msg": "hello api v1"
上面的路由的處理類都是使用匿名函數,處理的邏輯比較簡單的話,可以這么寫,但是還是不建議寫個匿名函數來處理,之后隨著項目越來越大,這里的路由定義會越來越多,如果還有大量的匿名函數的話,看著就會比較亂。
這里我們可以將處理handler 進行封裝。
先創建一個handlers 的文件夾,寫入以下代碼
package handlers
import "github.com/gin-gonic/gin"
type ApiV1 struct {
}
func (ApiV1) Get(c *gin.Context) {
c.JSON(200, gin.H{"msg": "handlers get request!"})
}
這里定義了一個ApiV1的結構體, 之后定義了一個Get 方法,然后在入口 server.go 文件中,修改原來的代碼,
func main() {
r := gin.Default()
apiv1_h := handlers.ApiV1{}
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"Msg": "Hello world",
})
})
apiv1 := r.Group("/api/v1")
{
apiv1.GET("/", apiv1_h.Get)
}
r.Run(":8080")
}
使用apiv1_h := handlers.ApiV1{}
?初始化一個ApiV1的結構體對象,在之后路由定義的時候,就可以直接使用該對象的Get方法,最好將相同前綴的放入一個括號中{}
,方法查看
{
apiv1.GET("/", apiv1_h.Get)
}
這里注意,處理handler 為?apiv1_h.Get
?, 而不是?apiv1_h.Get(c, *gin.Context)
上面的代碼都是以r.run(":8080")
?的方式啟動服務,但是有時候我們希望做一些個性化的設置,如一些讀寫超時,當然也可以調用gin.New()
?方法中得到的對象中進行設置,也可以直接使用http.Server
?中定義。
func main() {
r := gin.Default()
apiv1_h := handlers.ApiV1{}
apiv1 := r.Group("/api/v1")
{
apiv1.GET("/", apiv1_h.Get)
}
s := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: 10*time.Second,
WriteTimeout: 10*time.Second,
}
err := s.ListenAndServe()
if err != nil {
return
}
}
上面的代碼在處理請求的時候,都是返回json數據,由于現在主流開發使用前后端分離的模式,所以這里不太使用html 模板的方式返回數據了。
當使用第三方登錄的時候,全牽扯到網頁跳轉,網頁跳轉也非常簡單, 修改apiv1.go 文件
package handlers
import "github.com/gin-gonic/gin"
type ApiV1 struct {
}
func (*ApiV1) Get(c *gin.Context) {
c.Redirect(301, "https://www.baidu.com")
}
這樣在方法的對應的路由的時候,就會跳轉到百度了。
這里要注意,狀態碼必須處理300-308之間,否則會報錯
func (r Redirect) Render(w http.ResponseWriter) error {
if (r.Code < http.StatusMultipleChoices || r.Code > http.StatusPermanentRedirect) && r.Code != http.StatusCreated {
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
}
http.Redirect(w, r.Request, r.Location, r.Code)
return nil
}
gin 框架的基本搭建先記錄到這里,之后會介紹各種請求參數的獲取與校驗。
文章轉自微信公眾號@序語程言