iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 21
1
Software Development

Go繁不及備載系列 第 21

# Day21 Golang 網頁框架 gin 使用教學(GET、POST、ANY)

Day21 Golang 網頁框架 gin 使用教學(GET、POST、ANY)

gin,今天再喝一杯吧。

因為我們的目標是網頁伺服器,果不其然的要從網頁開始講起。

網頁請求方法 HTTP Method

HTTP Method 分成了八種GETPOSTDELETEPUTHEADTRACECONNECTOPTIONS,但在這我們只會簡介常用的GETPOST

  • GET:參數都放在網址裡,很不安全(要是參數是登入時的帳號、密碼,就會容易外洩),但方便開發的時候測試。
  • POST:參數不在網址裡,比較安全的作法。

Json格式

Json (JavaScript Object Notation) 是一種資料格式,由各種 陣列(Array)以及鍵值(Key-Value)所組成的結構話格式。
[]是陣列形式,裡面可以放各種物件
{}是鍵值形式,裡面可以放各種物件
兩種形式可以交錯使用,你中有我我中有你


Get方法 handler

以下使用gin不同的兩種方式(Context.Data,Context.JSON)來達成 返回json資料格式的效果:

func main() {
	router := gin.Default()

	router.GET("/json", returnJson)
	router.GET("/json2", returnJson2)

	router.Run(":80")
}

func returnJson(c *gin.Context) {
	m := map[string]string{"status": "ok"}
	j, _ := json.Marshal(m)
	c.Data(http.StatusOK, "application/json", j)
}

func returnJson2(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"狀態": "ok",
	})
}

json

(在這推薦安裝Chrome擴充套件 JSON Viewer Pro
或其他款可以在瀏覽器上方便看json檔案的套件,畫面看起來更舒適)
json2

另外,可以透過Chrome開發者工具 看到Content-Type為剛剛所設定的application/json
Content-Type

Struct 結構裡的tag

可以直接在struct中加入json tag,讓gin返回json格式的時候自動對應轉換。
(當然也有支援xml等格式,甚至可以自訂格式)

func returnJson3(c *gin.Context) {
	type Result struct {
		Status  string `json:"status"`
		Message string `json:"message"`
	}

	var result = Result{
		Status:  "OK",
		Message: "This is Json",
	}

	c.JSON(http.StatusOK, result)
}

詳見Day22-賦予API返回值的意義

【sturct 坑】

記得 struct中的 Status、Message要字首大寫,要對外暴露給gin套件取用


GET 接收參數

GET Method 是以網址帶參數的方式進行參數傳遞,可分成以下兩種:

  • 查詢參數(Query Params)
  • 路徑參數(Path Params)

查詢參數(Query Params)

127.0.0.1?user=id
參數名稱為user
其中的id就是使用者的ID。

127.0.0.1?user=Jack

為什麼叫作查詢參數、或稱作Query String呢?
因為他使用?問號來 Query參數
能以這方法夾帶表單參數(HTML Form),但傳遞表單時使用POST方法更為安全。

func main() {
	router := gin.Default()
	router.GET("/para1", para1)

	router.Run(":80")
}

func para1(c *gin.Context) {
	// input := c.DefaultQuery("input", "使用者沒有任何輸入。")  // 使用者沒有輸入參數時 可設定預設值
	input := c.Query("input")
	msg := []byte("您輸入的文字為: \n" + input)                     // 純文字(text/plain)中的換行是\n,網頁格式(html)中的換行才是<br />
	c.Data(http.StatusOK, "text/plain; charset=utf-8;", msg) // 如果沒有指定文字編碼、拿掉`charset=utf-8;`的話,中文會變亂碼。

}

成功執行的話,點開後會出現以下結果:
http://127.0.0.1/para1?input=%E5%93%88%E5%93%88%E6%98%AF%E6%88%91%E5%95%A6

para1

路徑參數(Path Params)

路徑即是參數,能以這種方式夾帶參數:

127.0.0.1/user/id
其中的user是參數名稱,可代表使用者頁面,
id就是使用者的ID。

127.0.0.1/user/Jack

func main() {
	router := gin.Default()
	router.GET("/para2/:input", para2)

	router.Run(":80")
}

func para2(c *gin.Context) {
	msg := c.Param("input")
	c.String(http.StatusOK, "您輸入的文字為: \n%s", msg) // 也可使用 `c.String`返回。第二個參數為組合樣式format
	// c.String(http.StatusOK, msg)                  // 如果沒有組合樣式,可直接輸入字串
}

成功執行的話,點開後會出現以下結果:
http://127.0.0.1/para2/%E5%93%88%E5%93%88%E6%98%AF%E6%88%91%E5%95%A6

para2

POST接收參數

post有寄信、發布訊息的意思

func main() {
	router := gin.Default()
    router.RedirectFixedPath = true
	router.POST("/post", post)
	router.Run(":80")
}

func post(c *gin.Context) {
	//msg := c.PostForm("input")
	msg := c.DefaultPostForm("input", "表單沒有input。") // 沒有輸入參數時 可設定預設值

	c.String(http.StatusOK, "您輸入的文字為: \n%s", msg)
}

由於POST Method參數都隱藏起來了,並非像GET在網址列填入參數就能達到目的,
開瀏覽器難以測試。在這邊我們會使用到Postman工具來做測試。

測試時選擇POST方法

POST

選擇Body,格式選擇form-data
並且填入表單的Key、Value
Form


Any

router.Any是任何方法都能夠 handle 的。

Any registers a route that matches all the HTTP methods.
包含 GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.

func main() {
	router := gin.Default()
	router.Any("/any", any)

	router.Run(":80")
}

func any(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status": "ok",
	})
}

gin預設是**大小寫敏感(case sensitivity)**的,只要對應的URI字符大小寫不同即視為不同,
這在一些使用情境下非常的不便。

gin 自動修正路徑

加上這行 重導向正確的URI,讓大小寫通吃。

router.RedirectFixedPath = true

上一篇
# Day20 Golang 網頁框架 gin 琴酒介紹
下一篇
# Day22 Golang 網頁框架 gin 實作小專案 (RESTful API)
系列文
Go繁不及備載35

尚未有邦友留言

立即登入留言