golang merangkum permintaan http

PHPz
Lepaskan: 2023-05-11 12:00:07
asal
612 orang telah melayarinya

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:

  1. Sokong kaedah HTTP seperti GET, POST, PUT dan DELETE.
  2. Menyokong tetapan pengepala permintaan, badan permintaan dan parameter permintaan.
  3. Menyokong tetapan tamat masa dan masa cuba semula.
  4. Menyokong pemformatan nilai pulangan ke dalam jenis data yang berbeza.

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:

  1. Isu rangkaian.

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.

  1. Pengendalian pengecualian.

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.

  1. Sokongan API RESTful.

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.

  1. Pengendalian nilai pulangan.

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:

  1. Tentukan Struktur permintaan HTTP.

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
}
Salin selepas log masuk
  1. memulakan permintaan HTTP.

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
}
Salin selepas log masuk

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,
        }
    }
Salin selepas log masuk

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
}
Salin selepas log masuk

Selepas berjaya memulakan permintaan HTTP, kita perlu mengeluarkan sumber untuk mengelakkan kebocoran memori yang disebabkan oleh permintaan berniat jahat:

defer resp.Body.Close()
Salin selepas log masuk
  1. Pengendalian pengecualian.

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.

  1. Sokongan API RESTful.

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.

  1. Pengendalian nilai pulangan.

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)
}
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan