iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 23
0
Modern Web

BeeGo系列 第 23

回應格式

因為在猶豫要不要用 BeeGo 寫 blog 網站了,所以有點不知道要寫什麼。

今天來介紹回應格式,預設的回應格式是 HTML,所以指定模版以後就搞定了。如果要輸出 JSON / JSONP / XML / YAML 的話,該怎麼使用呢?

使用

使用上其實蠻簡單的,主要呼叫這幾個 API 即可:

  • ServeJSON():表示輸出 JSON
  • ServeXML():表示輸出 XML
  • ServeJSONP():表示輸出 JSONP
  • ServeYAML():表示輸出 YAML

下面借網站上的範例來說明

type mystruct struct {
  FieldOne string `json:"field_one"`
}

// 輸出 JSON
func (this *AddController) Get() {
    mystruct := { ... }
    this.Data["json"] = &mystruct
    this.ServeJSON()
    // this.ServeXML()
    // this.ServeJSONP()
    // this.ServeYAML()
}

追蹤

讓我們追蹤程式,了解一下 BeeGo 是怎麼實作的。

從 this.ServeJSON() 可以看到 ServeJSON() 應該是由 Controller 所提供的。而 Controller 可以在 beego 原始碼的 controller.go 找到。

裏面的 ServeJSON()

// ServeJSON sends a json response with encoding charset.
func (c *Controller) ServeJSON(encoding ...bool) {
	var (
		hasIndent   = BConfig.RunMode != PROD
		hasEncoding = len(encoding) > 0 && encoding[0]
	)

	c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
}

可以看到,他會判斷 RunMode 來決定是否要增加縮排來提升可讀性,接著就使用 Conntroller 裡的 context 物件裡的 Output 去輸出 JSON。

Output.JSON() 可以在 context/output.go 找到 JSON() 這個函式。

func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
	output.Header("Content-Type", "application/json; charset=utf-8")
	var content []byte
	var err error
	if hasIndent {
		content, err = json.MarshalIndent(data, "", "  ")
	} else {
		content, err = json.Marshal(data)
	}
	if err != nil {
		http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
		return err
	}
	if encoding {
		content = []byte(stringsToJSON(string(content)))
	}
	return output.Body(content)
}

這函式主要是先指定 Content-Type 這個 header 為 application/json,接著使用 json module 對資料做 marshal ,最後再輸出。

其他格式的作法也都大同小異。

這邊順便複習一下 Django REST framework 的作法,DRF 是使用 Renderer 來指定輸出的格式,可以在 settings 裡去指定 DEFAULT_RENDERER_CLASSES ,也可以在個別的 APIView 裡去指定 renderer_classes 。DRF 的作法是比較彈性的,API endpoint 都是一致,但可以使用 format 這個共通的 query parameter 去指定要輸出的格式。

BeeGo 沒有像 DRF 一樣,設定一下就解決,但在程式上還是可以做的到的。

參考資料


上一篇
Tasks
下一篇
自動產出API文件
系列文
BeeGo30

尚未有邦友留言

立即登入留言