go 1.15

require (
github.com/gin-gonic/gin v1.7.4
)

之后使用go mod download 命令下載。

或者在項目目錄中直接運行?go get github.com/gin-gonic/gin@v1.7.4?命令,也會下載gin包,并且會自動添加到go.mod 文件中。

構建http 服務

新建一個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處理,會打印 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)

使用 http.Server 啟動服務

上面的代碼都是以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 框架的基本搭建先記錄到這里,之后會介紹各種請求參數的獲取與校驗。

文章轉自微信公眾號@序語程言

上一篇:

2024年及以后B2B電商的11大卓越趨勢

下一篇:

為開源項目 go-gin-api 增加 WebSocket 模塊
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費