SoFunction
Updated on 2025-03-01

Detailed explanation of Golang language HTTP client practice

Recently, I was learning Golang language and encountered a senior in the middle, and there was a learning principle: Learning By Doing. It is highly consistent with my previous experience in learning Java. After struggling in the pit of study some time ago for several days, I almost forgot this important successful experience.

So what to do exercises? Of course, it is combined with the current work, so I listed a route for myself, that is, to learn from interface testing, from functional testing to performance testing, and then master basic Server development skills.

First of all, we must first implement several commonly used functions for HTTP interface testing, mainly to obtain HTTPrequest objects, send request parsing responses, and basic configuration of HttpClient.

The implementation here is relatively simple and superficial, which reminds me of the beginning of the FunTester test framework, which also started with the API provided by the package, and I feel a lot of emotion.

Here I got from the HTTP-related API provided by the net/http package provided by the Golang SDK. Although it provides the best methods for encapsulation of(),() and(), it lacks flexibility in handling header and cookies in HTTPrequest, so I re-encapsulated the net/http encapsulation of the API for the second time. There are several omissions, such as the judgment of HTTPstatus and the automatic processing of Content-Type in the header. If this is enriched later, the temporary goal is to be useful.

HTTP client encapsulation

package task

import (
 "bytes"
 "encoding/json"
 "fmt"
 "io/ioutil"
 "net/http"
 "net/url"
 "strings"
 "time"
)

var Client  = clients()

// Res simulates the response structure// @Description:
type Res struct {
 Have string `json:"Have"`
}

// Get Get GET request// @Description:
// @param uri
// @param args
// @return *
func Get(uri string, args map[string]interface{}) * {
 uri = uri +  "?" +ToValues(args)
 request, _ := ("get", uri, nil)
 return request
}

// PostForm POST interface form// @Description:
// @param path
// @param args
// @return *
func PostForm(path string, args map[string]interface{}) * {
 request, _ := ("post", path, (ToValues(args)))
 return request
}

// PostJson POST request, JSON parameters// @Description:
// @param path
// @param args
// @return *
func PostJson(path string, args map[string]interface{}) * {
 marshal, _ := (args)
 request, _ := ("post", path, (marshal))

 return request
}

// ToValues ​​parses map into HTTP parameters for GET and POST form forms// @Description:
// @param args
// @return string
func ToValues(args map[string]interface{}) string {
 if args != nil && len(args) > 0 {
  params := {}
  for k, v := range args {
   (k, ("%v", v))
  }
  return ()
 }
 return ""
}

// Response Get response details, default []byte format// @Description:
// @param request
// @return []byte
func Response(request *) []byte {
 res, err := (request)
 if err != nil {
  return nil
 }
 body, _ := () // Read the response body, return as []byte defer ()
 return body
}

// clients initialize the request client// @Description:
// @return 
func clients()  {
 return {
  Timeout: (5) * , //Timeout time  Transport: &{
   MaxIdleConnsPerHost:   5,   //The maximum number of idle connections per route   MaxConnsPerHost:       100, //The maximum number of connections per route   IdleConnTimeout:       90 * ,
   TLSHandshakeTimeout:   10 * ,
   ExpectContinueTimeout: 1 * ,
  },
 }
}

// ParseRes parsing response// @Description:
// @receiver r
// @param res
func (r *Res) ParseRes(res []byte) {
 (res, r)
}

// ParseRes parses the response, converting []byte into an incoming object// @Description:
// @param res
// @param r
//
func ParseRes(res []byte, r interface{}) {
 (res, r)
}

Test scripts

package main

import (
 "fmt"
 "funtester/src/task"
 "io"
 "log"
 "net/http"
 "os"
 "time"
)

const (
 a = iota
 b
 c
 d
 e
)

func init() {
 ("./log/", 0777)
 ("./long/", 0777)
 file := "./log/" + string(().Format("20060102")) + ".log"
 openFile, _ := (file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
 writer := (, openFile)
 (writer)
 ( |  | )
}

func main() {

 url := "http://localhost:12345/test"
 args := map[string]interface{}{
  "name": "FunTester",
  "fun":  "fdsafj",
 }
 cookie := &{
  Name:  "token",
  Value: "fsjej09u0934jtej",
 }
 get := (url, args)
 ("user_agent", "FunTester")
 (cookie)
 response := (get)
 (string(response))
 form := (url, args)
 bytes := (form)
 (string(bytes))
 json := (url, args)
 res := (json)
 (string(res))

}

Console output

GOROOT=/usr/local/go #gosetup
GOPATH=/Users/oker/go #gosetup
/usr/local/go/bin/go build -o /private/var/folders/7b/0djfgf7j7p9ch_hgm9wx9n6w0000gn/T/GoLand/___go_build_funtester_src_m funtester/src/m #gosetup
/private/var/folders/7b/0djfgf7j7p9ch_hgm9wx9n6w0000gn/T/GoLand/___go_build_funtester_src_m
get request
Post request form
Post request json form

Process finished with the exit code 0

Testing Services

The moco_FunTester test framework is still implemented.

package 

import 
import 

class Share extends MocoServer {

    static void main(String[] args) {
        def util = new ArgsUtil(args)
        //                def server = getServerNoLog((0,12345))
        def server = getServer((0, 12345))
        (urlStartsWith("/test")).response("get request")
        (both(urlStartsWith("/test"), existForm("fun"))).response("post request form")
        (both(urlStartsWith("/test"), existParams("fun"))).response("Post request json form")
        (urlStartsWith("/qps")).response(qps(textRes("Congratulations on arriving at QPS!"), 1))
//        (delay(jsonRes(getJson("Have=Fun ~ Tester !")), 1000))
        ("Have Fun ~ Tester !")
        def run = run(server)
        waitForKey("fan")
        ()
    }
}

This is the end of this article about detailed explanation of the practice of Golang language HTTP client. For more related content on Golang HTTP client, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!