Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

基本使用

我们来看几个HTTP客户端请求的简单示例。

  1. 发送GET请求,并打印出返回值

    Code Block
    languagego
    if r, err := g.Client().Get(ctx, "https://goframe.org"); err != nil {
        panic(err)
    }
    defer r.Close()
    fmt.Println(r.ReadAllString())


  2. 发送GET请求,下载远程文件

    Code Block
    languagego
    if r, err := g.Client().Get(ctx, "https://goframe.org/cover.png"); err != nil {
        panic(err)
    }
    defer r.Close()
    gfile.PutBytes("/Users/john/Temp/cover.png", r.ReadAll())

    下载文件操作,小文件下载非常简单。需要注意的是,如果远程文件比较大时,服务端会分批返回数据,因此会需要客户端发多个GET请求,每一次通过Header来请求分批的文件范围长度,感兴趣的同学可自行研究相关细节。

  3. 发送POST请求,并打印出返回值

    Code Block
    languagego
    if r, err := g.Client().Post(ctx, "http://127.0.0.1:8199/form", "name=john&age=18"); err != nil {
        panic(err)
    }
    defer r.Close()
    fmt.Println(r.ReadAllString())

    传递多参数的时候用户可以使用&符号进行连接,注意参数值往往需要通过gurl.Encode编码一下。

  4. 发送POST请求,参数为map类型,并打印出返回值

    Code Block
    languagego
    if r, err := g.Client().Post(
        ctx, 
        "http://127.0.0.1:8199/form",
        g.Map{
            "submit"   : "1",
            "callback" : "http://127.0.0.1/callback?url=http://baidu.com",
        }
    )); err != nil {
        panic(err)
    }
    defer r.Close()
    fmt.Println(r.ReadAllString())

    传递多参数的时候用户可以使用&符号进行连接,也可以直接使用map(其实之前也提到,任意数据类型都支持,包括struct)。

  5. 发送POST请求,参数为JSON数据,并打印出返回值

    Code Block
    languagego
    if r, err := g.Client().Post(
        ctx,
        "http://user.svc/v1/user/create",
        `{"passport":"john","password":"123456","password-confirm":"123456"}`,
    ); err != nil {
        panic(err)
    }
    defer r.Close()
    fmt.Println(r.ReadAllString())

    可以看到,通过ghttp客户端发送JSON数据请求非常方便,直接通过Post方法提交即可,客户端会自动将请求的Content-Type设置为application/json

  6. 发送DELETE请求,并打印出返回值

    Code Block
    languagego
    if r, err := g.Client().Delete(ctx, "http://user.svc/v1/user/delete/1", "10000"); err != nil {
        panic(err)
    }
    defer r.Close()
    fmt.Println(r.ReadAllString())


*Bytes*Content方法

BytesContent后缀结尾的请求方法为直接获取返回内容的快捷方法,这些方法将会自动读取服务端返回内容并自动关闭请求连接。*Bytes方法用于获取[]byte类型结果,*Content方法用于获取string类型结果。需要注意的是,如果请求执行失败,返回内容将会为空。

  1. 发送GET请求,返回服务端返回内容

    Code Block
    languagego
     // 返回content为[]bytes类型
     content := g.Client().GetBytes(ctx, "https://goframe.org")


    Code Block
    languagego
     // 返回content为string类型
     content := g.Client().GetContent(ctx, "https://goframe.org")


  2. 发送POST请求,返回服务端返回内容

    Code Block
    languagego
    // 返回content为[]bytes类型
    content := g.Client().PostBytes(ctx,
        "http://user.svc/v1/user/create", 
        `{"passport":"john","password":"123456","password-confirm":"123456"}`,
    )


    Code Block
    languagego
    // 返回content为string类型
    content := g.Client().PostContent(ctx,
        "http://user.svc/v1/user/create", 
        `{"passport":"john","password":"123456","password-confirm":"123456"}`,
    )


*Var方法

Var后缀结尾的请求方法直接请求并获取HTTP接口结果为g.Var泛型类型便于转换。往往用于服务端返回格式为JSON/XML的情况,通过返回的g.Var泛型对象可根据需要自动解析。此外,如果请求失败或者请求结果为空,会返回一个空的g.Var泛型对象,不影响转换方法调用。

使用示例:

Code Block
languagego
type User struct {
    Id   int
    Name string
}


Code Block
languagego
// Struct
var user *User
g.Client().GetVar(ctx, url).Scan(&user)


Code Block
languagego
// Struct数组
var users []*User
g.Client().GetVar(ctx, url).Scan(&users)


New方法的使用

正常New方法的使用方式

Code Block
languagego
func ExampleNew() {
	var (
		ctx    = gctx.New()
		client = gclient.New()
	)

	if r, err := client.Get(ctx, "http://127.0.0.1:8999/var/json"); err != nil {
		panic(err)
	} else {
		defer r.Close()
		fmt.Println(r.ReadAllString())
	}

	// Output:
	// {"id":1,"name":"john"}
}

原生http.Client就支持了连接池的使用, 只需要设置http.Tranport的属性即可支持. 

同时注意在调用Get方法拿到Response对象后, 需要调用ReadAllString()获取Body, 否则程序会阻塞.

Code Block
languagego
func ExampleNew_MultiConn_Recommend() {
	var (
		ctx    = gctx.New()
		client = g.Client()
	)

	// controls the maximum idle(keep-alive) connections to keep per-host
	client.Transport.(*http.Transport).MaxIdleConnsPerHost = 5

	for i := 0; i < 5; i++ {
		go func() {
			if r, err := client.Get(ctx, "http://127.0.0.1:8999/var/json"); err != nil {
				panic(err)
			} else {
				fmt.Println(r.ReadAllString())
				r.Close()
			}
		}()
	}

	time.Sleep(time.Second * 1)

	// Output:
	//{"id":1,"name":"john"}
	//{"id":1,"name":"john"}
	//{"id":1,"name":"john"}
	//{"id":1,"name":"john"}
	//{"id":1,"name":"john"}
}



Panel
titleContent Menu

Table of Contents