Go組件學習——Web框架Gin

之前學Java的時候,和Spring全家桶打好關係就好了,從Spring、Spring MVC到SpringBoot,一脈相承。html

對於一個Web項目,使用Spring MVC,就能夠基於MVC的思想開發項目了,不論是應對先後端分離仍是不分離的場景,你均可以輕鬆駕馭。由於你只要知道,你用的是一個Web開發框架就好了。前端

相比於Spring在Java一家獨大的局面,Go生態中的Web框架還在百家爭鳴的階段。從今天開始學習一款基於Go語言開發的Web開發框架Gin。git

簡介

Github:https://github.com/gin-gonic/gingithub

語言:Go語言json

官網:https://gin-gonic.com/後端

 

環境搭建

Go版本:1.12.4瀏覽器

系統:macOS服務器

依賴管理工具:go mod微信

IDE:Goland閉包

由於我使用了go mod,因此引用gin的依賴算是很方便了。

如何建立一個go mod管理的新項目以及如何將老項目改造爲go mod,能夠參見這篇文章:https://juejin.im/post/5c8e503a6fb9a070d878184a,寫的很詳細了。

這就是個人go-demo:https://github.com/DMinerJackie/go-demo項目的全部第三方依賴了。

那麼如何添加gin的依賴呢?有如下三種方式

  • 直接新建一個基於gin的example程序文件,而後執行 go build xxx.go或者 go run xxx.go命令,go mod就會自動幫你下載gin依賴並更新go.mod文件。

  • 同上,仍是新建一個example程序文件,而後在項目根目錄下執行 go mod tidy命令,go mod會幫你安排上。這個命令能夠幫助你移除不須要的依賴,並拉取引用你須要的依賴。

  • 在go.mod文件中手動添加依賴相似 github.com/gin-gonic/gin v1.4.0這種。

幾乎不用什麼繁瑣的步驟,就完成了環境搭建。下面開始寫第一個基於Gin的demo

 

第一個Demo

一、新建文件helloworld.go

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() // 監聽並在 0.0.0.0:8080 上啓動服務 } 

  

二、點擊執行該程序

從控制檯程序能夠看出服務已經啓動,而且開始監聽8080端口

三、訪問接口

接下來咱們在瀏覽器輸入localhost:8080/ping便可看到程序返回的結果

一個極簡的Web服務器就這樣搭建完成並對外訪問了。

上面的代碼中

經過 r:=gin.Default()聲明一個gin的引擎,後續的操做都是基於這個引擎的。

經過 r.GET申明一個能夠訪問的路由,定義的HTTP請求方式爲GET請求。同時定義了請求後對應的處理方式,即一個閉包函數聲明以JSON格式返回的鍵值對。

經過 r.Run()監聽指定端口並啓動服務

 

其餘Demo

一、渲染HTML

雖然如今不少都倡導並實行先後端分離了,即後端只提供HTTP接口,前端負責調用HTTP接口以及頁面渲染。

但仍是有先後端揉在一塊兒的使用場景,gin就提供了這種能力。

具體的作法是提供一個HTML模板,服務端將獲得的數據填充到模板中實現頁面的渲染。

import ( "github.com/gin-gonic/gin" "net/http" ) func main() { router := gin.Default() router.LoadHTMLGlob("main/src/gin-example/examples/templates/**/*") router.GET("/posts/index", func(c *gin.Context) { c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ "title": "Posts", }) }) router.GET("/users/index", func(c *gin.Context) { c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ "title": "Users", }) }) router.Run(":8080") } 

  

index.tmpl

{{ define "posts/index.tmpl" }} <html><h1> {{ .title }} </h1> <p>Using posts/index.tmpl</p> </html> {{ end }} 

  

user.tmpl

{{ define "users/index.tmpl" }} <html><h1> {{ .title }} </h1> <p>Using users/index.tmpl</p> </html> {{ end }} 

  

對應的HTML模板文件目錄結構以下

代碼部分

router.LoadHTMLGlob用於指明HTML模板文件的路徑

router.GET同上,定義訪問路由和返回結果,不一樣於第一個Demo的是,這裏有賦值填充的過程,好比

c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ "title": "Posts", }) 

  

將index.tmpl中定義的 .title替換爲"Posts"

執行結果以下

二、PureJSON

func main() { r := gin.Default() // 提供 unicode 實體 r.GET("/json", func(c *gin.Context) { c.JSON(200, gin.H{ "html": "<b>Hello, 世界!</b>", }) }) // 提供字面字符 r.GET("/purejson", func(c *gin.Context) { c.PureJSON(200, gin.H{ "html": "<b>Hello, 世界!</b>", }) }) // 監聽並在 0.0.0.0:8080 上啓動服務 r.Run(":8080") } 

  

這裏兩個GET方法惟一不一樣的就是要渲染的內容一個使用JSON()方法一個使用PureJSON()方法。

啓動程序後,咱們看下訪問結果有什麼不一樣

能夠看出JSON()渲染的會有中文以及標籤轉爲unicode編碼,可是使用PureJSON()渲染就是原樣輸出(個人瀏覽器裝了插件,會自動解碼,因此不點擊右邊的」RAW「兩個接口返回的結果是同樣的)。

這個問題,本週咱們服務端在和客戶端對接的時候還遇到了,由於框架返回的JSON串就是通過編碼的,可是單獨請求放到瀏覽器是沒有問題的,客戶端收到的倒是通過編碼的,最後排查發現是瀏覽器插件解碼了。

三、渲染多種數據交換格式的數據

gin支持渲染XML、JSON、YAML和ProtoBuf等多種數據格式

import ( "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/testdata/protoexample" "net/http" ) func main() { r := gin.Default() // gin.H 是 map[string]interface{} 的一種快捷方式 r.GET("/someJSON", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) }) r.GET("/moreJSON", func(c *gin.Context) { // 你也可使用一個結構體 var msg struct { Name string `json:"user"` Message string Number int } msg.Name = "Lena" msg.Message = "hey" msg.Number = 123 // 注意 msg.Name 在 JSON 中變成了 "user" // 將輸出:{"user": "Lena", "Message": "hey", "Number": 123} c.JSON(http.StatusOK, msg) }) r.GET("/someXML", func(c *gin.Context) { c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) }) r.GET("/someYAML", func(c *gin.Context) { c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) }) r.GET("/someProtoBuf", func(c *gin.Context) { reps := []int64{int64(1), int64(2)} label := "test" // protobuf 的具體定義寫在 testdata/protoexample 文件中。 data := &protoexample.Test{ Label: &label, Reps: reps, } // 請注意,數據在響應中變爲二進制數據 // 將輸出被 protoexample.Test protobuf 序列化了的數據 c.ProtoBuf(http.StatusOK, data) }) // 監聽並在 0.0.0.0:8080 上啓動服務 r.Run(":8080") } 

  

今天先到這,後面再看看gin的源碼。

 

若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的「推薦」將是我最大的寫做動力!若是您想持續關注個人文章,請掃描二維碼,關注JackieZheng的微信公衆號,我會將個人文章推送給您,並和您一塊兒分享我平常閱讀過的優質文章。

相關文章
相關標籤/搜索