在 Go Echo 框架中操作 HTTP 請求 (1)
更新 @ 2019-12-13: 由 Go 1.13 開始,請使用內置的 Go Module 來管理套件。
在上一篇文章中,我們討論瞭如何在 Echo 框架中設置嵌套樣板。
在接下來的部分,我們將繼續介紹如何在 Echo 服務器中發出 HTTP 請求並將結果呈現在客戶端。讓我們從上一篇文章中的例子開始。
設置 API 端點
首先,創建一個新的 API 端點(endpoint)來返回一個簡單的 JSON ,這個稍後會被 Echo 服務器本身調用。
在 api 文件夾中建立新端點
與寫死的 JSON 請求不同,這個新 API 端點的請求結構將被定義在 model/example_request.go 這文件中,在實現時它的內容可以是一個 JSON 物件、HTML 表格或網址參數所提供,然後將其返回給客戶端。
model/example_request.go
package model type ExampleRequest struct { FirstName string `json:"first_name" form:"first_name" query:"first_name"` LastName string `json:"last_name" form:"last_name" query:"last_name"` }
api/get_full_name.go
package api import ( "fmt""net/http" "github.com/labstack/echo" "gitlab.com/ykyuen/golang-echo-template-example/model" ) func GetFullName(c echo.Context) error { // Bind the input data to ExampleRequest exampleRequest := new(model.ExampleRequest) if err := c.Bind(exampleRequest); err != nil { return err } // Manipulate the input data greeting := exampleRequest.FirstName + " " + exampleRequest.LastName return c.JSONBlob( http.StatusOK, []byte( fmt.Sprintf(`{ "first_name": %q, "last_name": %q, "msg": "Hello %s" }`, exampleRequest.FirstName, exampleRequest.LastName, greeting), ), ) }
設置上述 API 端點的路由
在 main.go
中添加我們的新 API 端點路由。
... func main() { // Echo instance e := echo.New() // Instantiate a template registry with an array of template set // Ref: https://gist.github.com/rand99/808e6e9702c00ce64803d94abff65678 templates := make(map[string]*template.Template) templates["home.html"] = template.Must(template.ParseFiles("view/home.html", "view/base.html")) templates["about.html"] = template.Must(template.ParseFiles("view/about.html", "view/base.html")) e.Renderer = &TemplateRegistry{ templates: templates, } // Route => handler e.GET("/", handler.HomeHandler) e.GET("/about", handler.AboutHandler) // Route => api e.GET("/api/get-full-name", api.GetFullName) // Start the Echo server e.Logger.Fatal(e.Start(":1323")) }
測試新的 API 端點
運行 Echo 服務器來測試一下。
這個新端點可以直接為瀏覽器或其它客戶端提供服務,也可以被 Echo 服務器本身調用。
從 Echo 服務器調用 API
建立回應結構型別
與 model/example_request.go 類似,我們需要定義一個 HTTP 回應結構型別。
model/example_response.go
package model type ExampleResponse struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` Msg string `json:"msg"` }
在 about 頁面中顯示回應的資訊
修改 about handler 的代碼,使其顯示 HTTP 回應的資訊。
handler/about_handler.go
package handler import ( "encoding/json""io/ioutil""net/http" "github.com/labstack/echo" "gitlab.com/ykyuen/golang-echo-template-example/model" ) func AboutHandler(c echo.Context) error { tr := &http.Transport{} client := &http.Client{Transport: tr} // Call the api resp, err := client.Get( "http://localhost:1323/api/get-full-name?first_name=Kit&last_name=Yuen", ) if err != nil { return err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) // Unmarshal the response into a ExampleResponse struct var exampleResponse model.ExampleResponse if err = json.Unmarshal(body, &exampleResponse); err != nil { return err } // Please note the the second parameter "about.html" is the template name and should // be equal to one of the keys in the TemplateRegistry array defined in main.go return c.Render(http.StatusOK, "about.html", map[string]interface{}{ "name": "About", "msg": exampleResponse.Msg, }) }
測試 about 頁面
啟動 Echo 服務器並瀏覽 about 頁面,我們可以看到新的問候語。
項目結構
進行上述更改後,項目結構應如下圖所示。(項目重命名為 handling-http-request-in-go-echo-example-1,如果要更改項目名稱,請確保正確設置 Golang 代碼中的 import 語句。)
handling-http-request-in-go-echo-example-1/ ├── api/ # folder of api endpoints │ ├── get_full_name.go # api for get full name ├── handler/ # folder of request handlers │ ├── home_handler.go # handler for home page │ └── about_handler.go # handler for about page ├── model/ # folder of custom struct types │ ├── example_request.go # struct type of get_full_name request │ └── example_response.go # hstruct type of get_full_name response ├── vendor/ # dependencies managed by dep │ ├── github.com/* │ └── golang.org/* ├── view/ # folder of html templates │ ├── base.html # base layout template │ ├── home.html # home page template │ └── about.html # about page template ├── Gopkg.lock # dep config file ├── Gopkg.toml # dep config file └── main.go # programme entrypoint
總結
本文介紹如何在 Echo 框架中設置簡單的 API 端點。由於 Go 是一種強型別語言,因此我們必須先將 JSON 請求與回應的結構型別,然後才能操作其內容。例如:
- 在 api/get_full_name.go 將 GET 請求綁定到 exampleRequest。
- 在 handler/about_handler.go 將 GET 回應解組為 exampleResponse。
要調用 API,我們可以直接使用 Go 內建的 net/http 標準函式庫。
完整的例子可以在此 gitlab.com 代碼庫上找到。