以 Go 語言快速實作 HTTP GET/POST API
(同步發表於 Cepave)
維基百科中提到:
目前在三種主流的Web服務實現方案中,因為REST模式與複雜的SOAP和XML-RPC相比更加簡潔,越來越多的web服務開始採用REST風格設計和實現。
…
符合 REST 設計風格的 Web API 稱為 RESTful API。它從以下三個方面資源進行定義:直觀簡短的資源地址、傳輸的資源、對資源的操作。
那麼我們要如何使用 Go 語言原生的函式庫建立簡單的 Web Server 提供 GET/POST 接口呢?讓我們透過 Hello World 的範例來說明。
建立 HTTP Server 接收請求
- 透過 ,我們可以定義 callback 函式所要負責的 URI。http.HandleFunc("/", callback)
- 呼叫 取出參數。同時適用於 GET/POST,所以為了減少行數我將範例中 GET/POST 一併處理。http.Request.ParseForm()
- 透過 取出姓氏與名字。http.Request.FormValue("key")
- 最後,將字串以 輸出,client 端即可在網頁上看到對應的訊息囉!http.ResponseWriter.Write("Hello World")
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/cepave", func(w http.ResponseWriter, req *http.Request) {
req.ParseForm()
if req.Method == "GET" || req.Method == "POST" {
fmt.Println(req.ContentLength)
firstname := req.FormValue("firstname")
lastname := req.FormValue("lastname")
w.Write([]byte(fmt.Sprintf("[%s] Hello, %s %s!", req.Method, firstname, lastname)))
} else {
http.Error(w, "The method is not allowed.", http.StatusMethodNotAllowed)
}
})
err := http.ListenAndServe(":9000", nil)
if err != nil {
fmt.Println("ListenAndServe failed: ", err)
}
}
實際發送請求來試試!
完成了 Server 端程式之後,我們可以透過
GET/POST 發送請由分別是透過
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
// POST
resp, err := http.PostForm("http://localhost:9000/cepave",
url.Values{"firstname": {"Kordan"}, "lastname": {"Ou"}})
if err != nil {
fmt.Println(err)
} else {
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("POST OK: ", string(body), resp)
}
// GET
resp, err = http.Get("http://localhost:9000/cepave?firstname=Kordan&lastname=Ou")
if err != nil {
fmt.Println(err)
} else {
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("GET OK: ", string(body), resp)
}
}
如果只是想測試 API,我們也可以打開終端機直接輸入以下命令:
$curl -X POST -d "firstname=Kordan&&lastname=Ou" localhost:9000/cepave
[POST] Hello, Kordan Ou!
如果是有巢狀結構的 JSON,我們可以這樣發 HTTP POST:
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
var jsonStr = []byte({ "endpoint_counters": [ { "endpoint": "host1", "counter": "load.1min" }, { "endpoint": "host2", "counter": "cpu.idle" } ], "start": 1437375109, "end": 1437377109, "cf": "AVERAGE" }
)
url := "http://example.com/graph/history"
fmt.Println("URL:>", url)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
req.Header.Set("X-Custom-Header", "myvalue")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(body))
}
透過以上幾個範例,應該可以感受到 Go 語言的簡潔以及內建函式庫的強大吧?!