基於Gin框架的web後端開發(二): JSON資料生成

LiberHome發表於2022-06-12

基於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

相關文章