上一章介紹到,如何建構 http server,那這篇就來教大家如何使用 http reqeust,一樣分兩個部分,一個是標準的函式庫用法,一個是小弟自己在包裝過方便使用跟資源控管的函式庫。
原生 package 有提幾個簡易就能輕易做到 http 的 GET
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
res, err := http.Get("https://blog.syhlion.tw/sitemap.xml")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
sitemap, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", sitemap)
}
用之前介紹過的 ioutil.ReadAll 去讀 res.Body ,這樣就能輕鬆取回 http response
這邊要注意一下,res.Body 讀取完,要記得 Close,不然會有 memory leak 等相關問題
上面的方法有另一種形式變形的用法
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
client := &http.Client{}
//這邊可以任意變換 http method GET、POST、PUT、DELETE
req, err := http.NewRequest("GET", "https://blog.syhlion.tw/sitemap.xml", nil)
if err != nil {
log.Println(err)
return
}
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
if err != nil {
log.Println(err)
return
}
defer resp.Body.Close()
sitemap, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return
}
fmt.Printf("%s", sitemap)
}
這是我因應業務需求,需要有大量可以存取各式 rest api 並且又要控制好併發數量,而開發出來的套件,使用方式如下
package main
import (
"fmt"
"github.com/syhlion/greq"
"github.com/syhlion/requestwork.v2"
"log"
)
func main() {
//need import https://github.com/syhlion/requestwork.v2
// 這是最高同時併發的控制,是 greq 的核心套件
worker := requestwork.New(50)
client := greq.New(worker, 15*time.Second)
//GET
data, httpstatus, err := client.Get("https://tw.yahoo.com", nil)
if err != nil {
log.Println(err)
return
}
fmt.Printf("data:%s ,httpstatus:%d", data, httpstatus)
//POST
v := url.Values{}
//post form data
v.Add("data", string(data))
data, httpstatus, err := client.Post("https://tw.yahoo.com", bytes.NewBufferString(v.Encode()))
if err != nil {
log.Println(err)
return
}
fmt.Printf("data:%s ,httpstatus:%d", data, httpstatus)
}
套件上已經有在內部做釋放資源 Close 的動作,所以不需要像原生的套件一樣,需要特地把 Body.Close()。