简介
gentlemangentlemannet/httpgentleman
快速使用
先安装:
$ go get gopkg.in/h2non/gentleman.v2
后使用:
package mainimport ( "fmt" "gopkg.in/h2non/gentleman.v2")func main() { cli := gentleman.New() cli.URL("https://dog.ceo") req := cli.Request() req.Path("/api/breeds/image/random") req.SetHeader("Client", "gentleman") res, err := req.Send() if err != nil { fmt.Printf("Request error: %vn", err) return } if !res.Ok { fmt.Printf("Invalid server response: %dn", res.StatusCode) return } fmt.Printf("Body: %s", res.String())}
gentlemanv1v2v2v2gentleman
gentleman.New()cliclicli.URL()cli.Request()reqreq.Path()req.Header()HeaderClientgentlemanreq.Send()resres
public-apishttps://dog.ceo/api/breeds/image/random
Body: {"message":"https://images.dog.ceo/breeds/malamute/n02110063_10567.jpg","status":"success"}
statussuccessmessage
插件
gentlemangentlemangentlemanplugins
body
body
package mainimport ( "fmt" "gopkg.in/h2non/gentleman.v2" "gopkg.in/h2non/gentleman.v2/plugins/body")func main() { cli := gentleman.New() cli.URL("http://httpbin.org/post") data := map[string]string{"foo": "bar"} cli.Use(body.JSON(data)) req := cli.Request() req.Method("POST") res, err := req.Send() if err != nil { fmt.Printf("Request error: %s\n", err) return } if !res.Ok { fmt.Printf("Invalid server response: %d\n", res.StatusCode) return } fmt.Printf("Status: %d\n", res.StatusCode) fmt.Printf("Body: %s", res.String())}
import "gopkg.in/h2non/gentleman.v2/plugins/body"
clireqUse()cli.Use()clireq.Use()req.Use(body.JSON(data))body.JSON()dataContent-Type/Content-Lengthreq.Method("POST")http://httpbin.org/post
Status: 200Body: { "args": {}, "data": "{\"foo\":\"bar\"}\n", "files": {}, "form": {}, "headers": { "Accept-Encoding": "gzip", "Content-Length": "14", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "gentleman/2.0.4", "X-Amzn-Trace-Id": "Root=1-5e8dd0c7-ab423c10fb530deade846500" }, "json": { "foo": "bar" }, "origin": "124.77.254.163", "url": "http://httpbin.org/post"}
发送 XML 格式与上面的非常类似:
type User struct { Name string `xml:"name"` Age int `xml:"age"`}func main() { cli := gentleman.New() cli.URL("http://httpbin.org/post") req := cli.Request() req.Method("POST") u := User{Name: "dj", Age: 18} req.Use(body.XML(u)) // ...}
后半部分一样的代码我就省略了,运行结果:
Status: 200Body: { "args": {}, "data": "<User><name>dj</name><age>18</age></User>", "files": {}, "form": {}, "headers": { "Accept-Encoding": "gzip", "Content-Length": "41", "Content-Type": "application/xml", "Host": "httpbin.org", "User-Agent": "gentleman/2.0.4", "X-Amzn-Trace-Id": "Root=1-5e8dd339-830dba04536ceef247156746" }, "json": null, "origin": "222.64.16.70", "url": "http://httpbin.org/post"}
header
headerUser-Agentheadercli
package mainimport ( "fmt" "gopkg.in/h2non/gentleman.v2" "gopkg.in/h2non/gentleman.v2/plugins/headers")func main() { cli := gentleman.New() cli.URL("https://api.thecatapi.com") cli.Use(headers.Set("x-api-key", "479ce48d-db30-46a4-b1a0-91ac4c1477b8")) cli.Use(headers.Del("User-Agent")) req := cli.Request() req.Path("/v1/breeds") res, err := req.Send() if err != nil { fmt.Printf("Request error: %s\n", err) return } if !res.Ok { fmt.Printf("Invalid server response: %d\n", res.StatusCode) return } fmt.Printf("Status: %d\n", res.StatusCode) fmt.Printf("Body: %s", res.String())}
https://api.thecatapi.com479ce48d-db30-46a4-b1a0-91ac4c1477b8thecatapix-api-key
headerscligentlemanUser-AgentgentlemanUser-Agent: gentleman/2.0.4header.Del()
输出内容太多,我这里就不贴了。
query
?query stringgentlemanquerypagelimit
package mainimport ( "fmt" "gopkg.in/h2non/gentleman.v2" "gopkg.in/h2non/gentleman.v2/plugins/headers" "gopkg.in/h2non/gentleman.v2/plugins/query")func main() { cli := gentleman.New() cli.URL("https://api.thecatapi.com") cli.Use(headers.Set("x-api-key", "479ce48d-db30-46a4-b1a0-91ac4c1477b8")) cli.Use(query.Set("attach_breed", "beng")) cli.Use(query.Set("limit", "2")) cli.Use(headers.Del("User-Agent")) req := cli.Request() req.Path("/v1/breeds") req.Use(query.Set("page", "1")) res, err := req.Send() if err != nil { fmt.Printf("Request error: %s\n", err) return } if !res.Ok { fmt.Printf("Invalid server response: %d\n", res.StatusCode) return } fmt.Printf("Status: %d\n", res.StatusCode) fmt.Printf("Body: %s", res.String())}
cli
cli.Use(query.Set("attach_breed", "beng"))cli.Use(query.Set("limit", "2"))
req
req.Use(query.Set("page", "1"))
query stringquery.Del()
url
/info/user/1/info/book/1/info/:class/1userbookgentlemanurl
package mainimport ( "fmt" "os" "gopkg.in/h2non/gentleman.v2" "gopkg.in/h2non/gentleman.v2/plugins/headers" "gopkg.in/h2non/gentleman.v2/plugins/url")func main() { cli := gentleman.New() cli.URL("https://api.thecatapi.com/") cli.Use(headers.Set("x-api-key", "479ce48d-db30-46a4-b1a0-91ac4c1477b8")) cli.Use(url.Path("/v1/:type")) for _, arg := range os.Args[1:] { req := cli.Request() req.Use(url.Param("type", arg)) res, err := req.Send() if err != nil { fmt.Printf("Request error: %s\n", err) return } if !res.Ok { fmt.Printf("Invalid server response: %d\n", res.StatusCode) return } fmt.Printf("Status: %d\n", res.StatusCode) fmt.Printf("Body: %s\n", res.String()) }}
thecatapi/v1/breeds/v1/votes/v1/categoriesurlcliurl.Path("/v1/:type")url.Param("type", arg)type
$ go run main.go breeds votes categories
其他
gentlemanauthcookiescompressionproxyredirecttimeoutretryconsul
自定义
如果内置的和第三方的插件都不能满足我们的需求,我们还可以自定义插件。自定义的插件需要实现下面的接口:
// src/gopkg.in/h2non/gentleman.v2/plugin/plugin.gotype Plugin interface { Enable() Disable() Disabled() bool Remove() Removed() bool Exec(string, *context.Context, context.Handler)}
Exec()
PlugingentlemanLayerNewRequestPlugin/NewResponsePlugin/NewErrorPlugin
我们现在来实现一个插件,在请求之前输出一行信息,收到响应之后输出一行信息:
package mainimport ( "fmt" "gopkg.in/h2non/gentleman.v2" c "gopkg.in/h2non/gentleman.v2/context" "gopkg.in/h2non/gentleman.v2/plugin")func main() { cli := gentleman.New() cli.URL("https://httpbin.org") cli.Use(plugin.NewRequestPlugin(func(ctx *c.Context, h c.Handler) { fmt.Println("request") h.Next(ctx) })) cli.Use(plugin.NewResponsePlugin(func(ctx *c.Context, h c.Handler) { fmt.Println("response") h.Next(ctx) })) req := cli.Request() req.Path("/headers") res, err := req.Send() if err != nil { fmt.Printf("Request error: %s\n", err) return } if !res.Ok { fmt.Printf("Invalid server response: %d\n", res.StatusCode) return } fmt.Printf("Status: %d\n", res.StatusCode) fmt.Printf("Body: %s", res.String())}
NewRequestPlugin/NewResponsePluginfunc(ctx *c.Context, h c.Handler)ctxRequestResponse
总结
gentleman
大家如果发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue????
参考
我
-
欢迎关注我的微信公众号【GoUpUp】,共同学习,一起进步~