Resty 非常好用的链式HTTP客户端
原创Go库http链式大约 4 分钟
Resty 非常好用的链式HTTP客户端
安装
go get -u github.com/go-resty/resty/v2
Hello Resty
一个简单的示例
import (
"fmt"
"log"
"github.com/go-resty/resty/v2"
)
func main() {
client := resty.New()
resp, err := client.R().Get("https://baidu.com")
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Body())
}
Request
使用起来很简单,都是链式编程,想添加设置什么都有对应的setter
// Request 中的set方法
// 请求头
SetHeader(header string, value string) *Request
SetHeaders(headers map[string]string) *Request
SetHeaderMultiValues(headers map[string][]string) *Request
/*
相对于SetHeader会保留名称的原格式,而SetHeader将请求头名称转换为标准的格式(HTTP 规范是小写)
client.R().
SetHeaderVerbatim("all_lowercase", "available").
SetHeaderVerbatim("UPPERCASE", "available")
*/
SetHeaderVerbatim(header string, value string) *Request
// 路径参数
SetQueryParam(param string, value string) *Request // 一个个设置
SetQueryParams(params map[string]string) *Request // 传进去一个 map
SetQueryParamsFromValues(params url.Values) *Request
SetQueryString(query string) *Request // 拼接好的查询字符串 name=dj&age=18
/** rest-full 路径参数
client.R().
SetPathParams(map[string]string{
"user": "dj",
}).
Get("/v1/users/{user}/details")
*/
SetPathParam(param string, value string) *Request
SetPathParams(params map[string]string) *Request
// formdata 参数
SetFormData(data map[string]string) *Request
SetFormDataFromValues(data url.Values) *Request
// MultipartFormData 参数
SetFile(param string, filePath string) *Request
SetFiles(files map[string]string) *Request
SetFileReader(param string, fileName string, reader io.Reader) *Request
SetMultipartFormData(data map[string]string) *Request
SetMultipartField(param string, fileName string, contentType string, reader io.Reader) *Request
SetMultipartFields(fields ...*MultipartField) *Request
// body
SetBody(body interface{}) *Request
// 将json自动解析到结构体
SetResult(res interface{}) *Request // 200-299的成功响应
SetError(err interface{}) *Request // 大于399的错误响应
// trace
EnableTrace() *Request // 启用可以记录请求的每一步的耗时和其他信息
TraceInfo() TraceInfo // 详细信息 resp.Request.TraceInfo()
SetCookie(hc *http.Cookie) *Request
SetCookies(rs []*http.Cookie) *Request
SetContentLength(l bool) *Request
SetBasicAuth(username string, password string) *Request
SetAuthToken(token string) *Request
SetAuthScheme(scheme string) *Request
SetDigestAuth(username string, password string) *Request
SetContext(ctx context.Context) *Request
SetOutput(file string) *Request
SetSRV(srv *SRVRecord) *Request
SetDoNotParseResponse(parse bool) *Request
SetRawPathParam(param string, value string) *Request
SetRawPathParams(params map[string]string) *Request
SetJSONEscapeHTML(b bool) *Request
SetLogger(l Logger) *Request
SetDebug(d bool) *Request
示例
type WenXinBody struct {
Id string `json:"id"`
Object string `json:"object"`
Created int `json:"created"`
Result string `json:"result"`
IsTruncated bool `json:"is_truncated"`
NeedClearHistory bool `json:"need_clear_history"`
Usage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}
func main(){
client := resty.New()
wenXinBody := WenXinBody{}
url := "https://baidu.com"
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetBody(map[string]interface{}{
"messages": []map[string]string{
{
"role": "user",
"content": "解析【" + con + "】" + "中的英文单词或句子和中文翻译并分组为每个对象,对象字段为english,chinese,最终仅通过json字符串返回给我,格式如下[{\"english\": \"英文单词或句子\",\"chinese\": \"中文翻译\"},{\"english\": \"英文单词或句子\",\"chinese\": \"中文翻译\"}]",
},
},
"extra_parameters": map[string]bool{
"use_keyword": false,
"use_reference": false,
},
}).
SetQueryParam("access_token", "24.04f22b88f6007195742f19e3f4cd4f75.2592000.1707481399.282335-46811580").
SetResult(&wenXinBody).
Post(url)
fmt.Println(wenXinBody.Result)
}
自动 Unmarshal
Response
// Response 中的方法
Body() []byte
SetBody(b []byte) *Response
Status() string
StatusCode() int
Proto() string
Result() interface{}
Error() interface{}
Header() http.Header
Cookies() []*http.Cookie
String() string
Time() time.Duration
ReceivedAt() time.Time
Size() int64
RawBody() io.ReadCloser
IsSuccess() bool
IsError() bool
示例
func main() {
client := resty.New()
resp, err := client.R().Get("https://baidu.com")
if err != nil {
log.Fatal(err)
}
fmt.Println("Response Info:")
fmt.Println("Status Code:", resp.StatusCode())
fmt.Println("Status:", resp.Status())
fmt.Println("Proto:", resp.Proto())
fmt.Println("Time:", resp.Time())
fmt.Println("Received At:", resp.ReceivedAt())
fmt.Println("Size:", resp.Size())
fmt.Println("Headers:")
for key, value := range resp.Header() {
fmt.Println(key, "=", value)
}
fmt.Println("Cookies:")
for i, cookie := range resp.Cookies() {
fmt.Printf("cookie%d: name:%s value:%s\n", i, cookie.Name, cookie.Value)
}
}
Client
// Client 中的方法
SetHostURL(url string) *Client
SetBaseURL(url string) *Client
SetHeader(header string, value string) *Client
SetHeaders(headers map[string]string) *Client
SetHeaderVerbatim(header string, value string) *Client
SetCookieJar(jar http.CookieJar) *Client
SetCookie(hc *http.Cookie) *Client
SetCookies(cs []*http.Cookie) *Client
SetQueryParam(param string, value string) *Client
SetQueryParams(params map[string]string) *Client
SetFormData(data map[string]string) *Client
SetBasicAuth(username string, password string) *Client
SetAuthToken(token string) *Client
SetAuthScheme(scheme string) *Client
SetDigestAuth(username string, password string) *Client
R() *Request
NewRequest() *Request
// 中间件 监听以下情况的回调
OnBeforeRequest(m RequestMiddleware) *Client
OnAfterResponse(m ResponseMiddleware) *Client
OnError(h ErrorHook) *Client
OnSuccess(h SuccessHook) *Client
OnInvalid(h ErrorHook) *Client
OnPanic(h ErrorHook) *Client
SetPreRequestHook(h PreRequestHook) *Client
SetDebug(d bool) *Client
SetDebugBodyLimit(sl int64) *Client
OnRequestLog(rl RequestLogCallback) *Client
OnResponseLog(rl ResponseLogCallback) *Client
SetDisableWarn(d bool) *Client
SetAllowGetMethodPayload(a bool) *Client
SetLogger(l Logger) *Client
SetContentLength(l bool) *Client
SetTimeout(timeout time.Duration) *Client
SetError(err interface{}) *Client
SetRedirectPolicy(policies ...interface{}) *Client
SetRetryCount(count int) *Client
SetRetryWaitTime(waitTime time.Duration) *Client
SetRetryMaxWaitTime(maxWaitTime time.Duration) *Client
SetRetryAfter(callback RetryAfterFunc) *Client
SetJSONMarshaler(marshaler func(v interface{}) ([]byte, error)) *Client
SetJSONUnmarshaler(unmarshaler func(data []byte, v interface{}) error) *Client
SetXMLMarshaler(marshaler func(v interface{}) ([]byte, error)) *Client
SetXMLUnmarshaler(unmarshaler func(data []byte, v interface{}) error) *Client
AddRetryCondition(condition RetryConditionFunc) *Client
AddRetryAfterErrorCondition() *Client
AddRetryHook(hook OnRetryFunc) *Client
SetRetryResetReaders(b bool) *Client
SetTLSClientConfig(config *tls.Config) *Client
SetProxy(proxyURL string) *Client
RemoveProxy() *Client
SetCertificates(certs ...tls.Certificate) *Client
SetRootCertificate(pemFilePath string) *Client
SetRootCertificateFromString(pemContent string) *Client
SetOutputDirectory(dirPath string) *Client
SetRateLimiter(rl RateLimiter) *Client
SetTransport(transport http.RoundTripper) *Client
SetScheme(scheme string) *Client
SetCloseConnection(close bool) *Client
SetDoNotParseResponse(parse bool) *Client
SetPathParam(param string, value string) *Client
SetPathParams(params map[string]string) *Client
SetRawPathParam(param string, value string) *Client
SetRawPathParams(params map[string]string) *Client
SetJSONEscapeHTML(b bool) *Client
EnableTrace() *Client
DisableTrace() *Client
IsProxySet() bool
GetClient() *http.Client
Transport() (*http.Transport, error)
TraceInfo
信息
- DNSLookup:DNS 查询时间,如果提供的是一个域名而非 IP,就需要向 DNS 系统查询对应 IP 才能进行后续操作;
- ConnTime:获取一个连接的耗时,可能从连接池获取,也可能新建;
- TCPConnTime:TCP 连接耗时,从 DNS 查询结束到 TCP 连接建立;
- TLSHandshake:TLS 握手耗时;
- ServerTime:服务器处理耗时,计算从连接建立到客户端收到第一个字节的时间间隔;
- ResponseTime:响应耗时,从接收到第一个响应字节,到接收到完整响应之间的时间间隔;
- TotalTime:整个流程的耗时;
- IsConnReused:TCP 连接是否复用了;
- IsConnWasIdle:连接是否是从空闲的连接池获取的;
- ConnIdleTime:连接空闲时间;
- RequestAttempt:请求执行流程中的请求次数,包括重试次数;
- RemoteAddr:远程的服务地址,IP:PORT格式。
