基於Gin框架的web開發,總的來講有兩種:
- 第一種是後端使用go語言模板引擎完成整個web全棧開發,返回完整的html檔案給瀏覽器。
- 第二種是前後端分離,使用JSON互動
由於第一種方法耗費太多網路資源,效能差,耦合度高,目前已經基本被第二種模式取代,這篇部落格只介紹如何在Gin框架中返回JSON資料給前端或者移動端(俗稱JSON的渲染)。
生成JSON資料可以用map,也可以用結構體。下面先介紹map:
基於map的JSON資料生成
舉個例子,程式碼如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/json", func(c *gin.Context) {
//這裡構造伺服器要返回前端的資料,一共有兩種方法,第一種是:使用map將資料序列化
//,這個map的key是一個string, value是一個空的介面(這樣即可以實現接收任意型別的資料)
data := map[string]interface{}{
"name": "liber",
"message": "hey liber~",
"age": 16,
}
//這裡要返回json格式的資料,所以用c.JSON,這樣,資料就返回給請求方了
c.JSON(http.StatusOK, data)
})
r.Run(":9090")
}
測試結果如下:
由於用map來序列化json資料是很常見的寫法,Gin框架的作者將這種寫法封裝了一下:
//H is a shortcut for map[string]interface{}
type H map[string]interface{}
所以,我們可以直接使用gin.H{}來代替:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/json", func(c *gin.Context) {
//這裡構造伺服器要返回前端的資料,一共有兩種方法,第一種是:使用map將資料序列化
//,這個map的key是一個string, value是一個空的介面(這樣即可以實現接收任意型別的資料)
//data := map[string]interface{}{
// "name": "liber",
// "message": "hey liber~",
// "age": 16,
//}
data := gin.H{
"name": "libro",
"message": "hey libro~",
"age": 17,
}
//這裡要返回json格式的資料,所以用c.JSON,這樣,資料就返回給請求方了
c.JSON(http.StatusOK, data)
})
r.Run(":9090")
}
測試結果如下:
基於結構體的JSON資料生成
其實就是另一種寫法而已:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/json", func(c *gin.Context) {
//這裡構造伺服器要返回前端的資料,一共有兩種方法,第一種是:使用map將資料序列化
//,這個map的key是一個string, value是一個空的介面(這樣即可以實現接收任意型別的資料)
//data := map[string]interface{}{
// "name": "liber",
// "message": "hey liber~",
// "age": 16,
//}
data := gin.H{
"name": "libro",
"message": "hey libro~",
"age": 17,
}
//這裡要返回json格式的資料,所以用c.JSON,這樣,資料就返回給請求方了
c.JSON(http.StatusOK, data)
})
//這裡介紹生成JSON資料的第二種方法:利用結構體
//首先構造一個結構體
type msg struct {
Name string
Message string
Age int
}
//然後構建一個結構體的例項
r.GET("/another_json", func(c *gin.Context) {
data := msg{
Name: "libro",
Message: "hey libro~",
Age: 17,
}
c.JSON(http.StatusOK, data)
})
r.Run(":9090")
}
測試結果如圖:
不過需要注意的是,如果使用結構體,欄位開頭字母必須大寫,否則就沒辦法完成JSON的序列化,因為JSON序列化過程中使用到了Go內建的反射機制,小寫表示不可匯出。當然這也有解決之道,就是打tag:
//這裡假設 前端就需要小寫的name
type msg struct {
Name string `json: "name"`
Message string
Age int
}
其實我覺得,既然有坑,直接規定用第一種方法規避掉是一種簡潔&明智的選擇。
參考: bilibili