Dengan pembangunan Internet, permintaan HTTP telah menjadi standard untuk pembangunan bahagian belakang dan juga cara untuk bahagian hadapan untuk memulakan permintaan rangkaian. Di Golang, perpustakaan standard mempunyai pakej net/http terbina dalam, menyediakan klien dan pelayan HTTP yang lengkap. Walau bagaimanapun, merangkum perpustakaan permintaan HTTP membolehkan kami memulakan permintaan HTTP dengan lebih cekap dan mudah semasa proses pembangunan. Dalam artikel ini, kami akan membincangkan cara merangkum pustaka permintaan HTTP Golang.
1. Analisis Keperluan
Sebelum membungkus perpustakaan permintaan HTTP, kami perlu menjelaskan beberapa keperluan dan fungsi untuk mereka bentuk dan membangunkan perpustakaan kami dengan lebih baik. Di sini, kami percaya bahawa perpustakaan permintaan HTTP yang lengkap perlu mempunyai fungsi berikut:
Berdasarkan keperluan dan fungsi di atas, kami boleh mula mereka bentuk dan membangunkan perpustakaan permintaan HTTP kami.
2. Reka Bentuk dan Pelaksanaan
2.1 Titik Reka Bentuk
Apabila mereka bentuk perpustakaan permintaan HTTP kami, kami perlu mempertimbangkan beberapa perkara utama untuk mencapai Extensible yang sangat tersedia dan boleh dipercayai dan perpustakaan permintaan yang mudah digunakan. Secara khusus, kita harus mempertimbangkan aspek berikut:
Apabila membuat permintaan HTTP, kita mesti mempertimbangkan masalah rangkaian, seperti tamat masa sambungan, tamat masa permintaan, dsb. Oleh itu, perpustakaan permintaan HTTP kami perlu menyokong penetapan tamat masa sambungan dan tamat masa permintaan.
Apabila kami memulakan permintaan HTTP, pelbagai pengecualian yang tidak dapat diramalkan mungkin berlaku, seperti pengecualian rangkaian, pengecualian nilai pulangan, dsb. Untuk menjadikan perpustakaan permintaan HTTP kami lebih mantap, pengecualian ini perlu dikendalikan, contohnya, berdasarkan kod status http, maklumat pengecualian, dsb.
Dalam RESTful API, selalunya perlu menyerahkan data JSON atau data borang, dsb. Oleh itu, dalam perpustakaan permintaan HTTP kami, kami perlu menyokong penyerahan dan penghuraian data ini.
Selepas memulakan permintaan HTTP, kami perlu memproses nilai pulangan. Biasanya, format nilai pulangan antara muka API yang berbeza mungkin berbeza Oleh itu, kita perlu menyokong pemprosesan yang sepadan mengikut format nilai pulangan antara muka API.
2.2 Proses pelaksanaan
Berdasarkan titik reka bentuk di atas, apabila kita mula melaksanakan perpustakaan permintaan HTTP, kita boleh mengikuti langkah berikut:
Apabila merangkum perpustakaan permintaan HTTP, kami perlu merangkum maklumat permintaan HTTP. Secara khusus, kami boleh menentukan struktur permintaan HTTP untuk menyimpan dan memindahkan maklumat yang diperlukan untuk permintaan HTTP. Berikut ialah contoh struktur permintaan HTTP:
type Request struct { URL string Method string Headers map[string]string Body []byte Params map[string]string Timeout int RetryTimes int }
Selepas kami mentakrifkan struktur permintaan HTTP, kami boleh menghantar permintaan HTTP melalui perpustakaan standard Golang.
Sebagai contoh, kita boleh menggunakan kaedah http.NewRequest() untuk membuat permintaan HTTP:
req, err := http.NewRequest(req.Method, req.URL, bytes.NewBuffer(req.Body)) if err != nil { return nil, err }
Gunakan kaedah DialContext() dalam http.Transport untuk menetapkan tamat masa sambungan dan meminta tamat masa :
client := &http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: time.Duration(req.Timeout) * time.Second, KeepAlive: time.Duration(req.Timeout) * time.Second, }).DialContext, MaxIdleConns: 100, // http.ConnectionPool数量 IdleConnTimeout: 90 * time.Second, // http.ConnectionPool中连接的空闲超时时间 TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } }
Seterusnya, kita boleh menggunakan kaedah Do() untuk memulakan permintaan HTTP dan mendapatkan nilai pulangan:
resp, err := client.Do(req) if err != nil { return nil, err }
Selepas berjaya memulakan permintaan HTTP, kita perlu mengeluarkan sumber untuk mengelakkan kebocoran memori yang disebabkan oleh permintaan berniat jahat:
defer resp.Body.Close()
Apabila memulakan permintaan HTTP, pelbagai pengecualian yang tidak dapat diramalkan mungkin berlaku, seperti pengecualian rangkaian, pengecualian nilai pulangan, dsb. Oleh itu, pengecualian ini perlu dikendalikan dalam perpustakaan permintaan HTTP kami.
Sebagai contoh, kami boleh menyemak pengecualian permintaan HTTP berdasarkan kod status HTTP dan badan respons. Jika pengecualian berlaku, kami boleh mengembalikan maklumat ralat yang sepadan mengikut jenis pengecualian, supaya ia boleh ditemui dan diproses dalam masa semasa proses pembangunan.
Apabila memanggil RESTful API, kami perlu menyokong format penyerahan yang berbeza, seperti data JSON atau data borang, dsb. Untuk menjadikan perpustakaan permintaan HTTP kami lebih serba boleh, medan atribut ContentType boleh ditambah untuk menyokong format penyerahan yang berbeza. Pada masa yang sama, apabila menyerahkan data JSON, kami juga perlu mengekod data ke dalam format JSON.
Selepas memanggil antara muka, kita perlu memproses nilai pulangan. Secara amnya, format nilai pulangan antara muka API yang berbeza mungkin berbeza Oleh itu, kita perlu melakukan pemprosesan yang sepadan dalam aplikasi lapisan atas mengikut format nilai pulangan antara muka API. Sebagai contoh, anda boleh menetapkan kaedah penyahserikatan berdasarkan format nilai pulangan.
2.3 Pelaksanaan Kod
Berdasarkan titik reka bentuk di atas, apabila kita mula melaksanakan perpustakaan permintaan HTTP, kita boleh merujuk kepada pelaksanaan kod berikut:
package httpreq import ( "bytes" "encoding/json" "io/ioutil" "net" "net/http" "time" ) type Request struct { URL string Method string Headers map[string]string Body []byte Params map[string]string Timeout int RetryTimes int ContentType string } type Response struct { StatusCode int Body []byte } func Do(req Request) (*Response, error) { if req.Method == "" { req.Method = http.MethodGet } // 处理请求参数 if req.Params != nil { req.URL = AddQueryParams(req.URL, req.Params) } // 创建一个请求 httpRequest, err := http.NewRequest(req.Method, req.URL, bytes.NewBuffer(req.Body)) if err != nil { return nil, err } // 处理请求头 if req.Headers != nil { for k, v := range req.Headers { httpRequest.Header.Set(k, v) } } // 设置ContentType if req.ContentType != "" { httpRequest.Header.Set("Content-Type", req.ContentType) } // 设置请求超时 httpClient := &http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: time.Duration(req.Timeout) * time.Second, KeepAlive: time.Duration(req.Timeout) * time.Second, }).DialContext, MaxIdleConns: 100, // http.ConnectionPool数量 IdleConnTimeout: 90 * time.Second, // http.ConnectionPool中连接的空闲超时时间 TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, }, } // 发起请求 resp, err := httpClient.Do(httpRequest) if err != nil { return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } // 处理异常 if resp.StatusCode >= 400 { return nil, NewError(resp.StatusCode, body) } return &Response{StatusCode: resp.StatusCode, Body: body}, nil } func AddQueryParams(url string, params map[string]string) string { var queryParams string for k, v := range params { queryParams = queryParams + "&" + k + "=" + v } url = url + "?" + queryParams[1:] return url } func NewError(statusCode int, body []byte) error { errorMsg := string(body) if errorMsg == "" { errorMsg = http.StatusText(statusCode) } return &httpError{StatusCode: statusCode, Message: errorMsg} } type httpError struct { StatusCode int Message string } func (e *httpError) Error() string { return e.Message } func (r *Response) BindJSON(v interface{}) error { return json.Unmarshal(r.Body, v) } func (r *Response) BindText() string { return string(r.Body) }
3. Ringkasan
Melalui perbincangan di atas, kita dapati bahawa merangkum perpustakaan permintaan HTTP Golang bukanlah tugas yang sukar. Perkara utama ialah kita harus jelas tentang keperluan kita dan memahami beberapa butiran permintaan rangkaian, dan kemudian kita boleh menggunakan kaedah yang disediakan oleh perpustakaan standard untuk merangkum perpustakaan permintaan HTTP yang sangat baik di Golang. Pada masa yang sama, semasa proses pelaksanaan, kami juga perlu mempertimbangkan beberapa butiran, seperti pengendalian pengecualian, sokongan API RESTful, pemprosesan nilai pulangan, dsb. Melalui reka bentuk dan pelaksanaan yang teliti, kami boleh membangunkan perpustakaan permintaan HTTP berkualiti tinggi untuk menjadikan pembangunan Golang kami lebih cekap dan mudah.
Atas ialah kandungan terperinci golang merangkum permintaan http. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!