上一章介紹到,如何建構 http server,那這篇就來教大家如何使用 http reqeust,一樣分兩個部分,一個是標準的函式庫用法,一個是小弟自己在包裝過方便使用跟資源控管的函式庫。

net/http

原生 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)
}

github.com/syhlion/greq

這是我因應業務需求,需要有大量可以存取各式 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()。