- Constants
- Client">type Client
- ErrorHook">type ErrorHook
- Option">type Option
- Options">type Options
- Logger">type Logger
- PreRequestHook">type PreRequestHook
- RedirectPolicy">type RedirectPolicy
- RedirectPolicyFunc">type RedirectPolicyFunc
- Request">type Request
- RequestLog">type RequestLog
- RequestLogCallback">type RequestLogCallback
- RequestMiddleware">type RequestMiddleware
- Response">type Response
- ResponseError">type ResponseError
- ResponseLog">type ResponseLog
- ResponseLogCallback">type ResponseLogCallback
- ResponseMiddleware">type ResponseMiddleware
- RetryAfterFunc">type RetryAfterFunc
- RetryConditionFunc">type RetryConditionFunc
- TraceInfo">type TraceInfo
- User">type User
- 小技巧
Simple HTTP and REST client library for Go
ps: 个人感觉resty比colly好用,不错先用的colly, 然后转到了resty
文档:https://pkg.go.dev/github.com/go-resty/resty/v2
Constants
const (
MethodGet = "GET"
MethodPost = "POST"
MethodPut = "PUT"
MethodDelete = "DELETE"
MethodPatch = "PATCH"
MethodHead = "HEAD"
MethodOptions = "OPTIONS"
)
type Client
客户端结构用于创建带有客户端级别设置的Resty客户端,这些设置适用于客户端引发的所有请求
request的请求最后也是转到client去执行的
type Client struct {
HostURL string
QueryParam url.Values
FormData url.Values
Header http.Header
UserInfo *User
Token string
AuthScheme string
Cookies []*http.Cookie
Error reflect.Type
Debug bool
DisableWarn bool
AllowGetMethodPayload bool
RetryCount int
RetryWaitTime time.Duration
RetryMaxWaitTime time.Duration
RetryConditions []RetryConditionFunc
RetryAfter RetryAfterFunc
JSONMarshal func(v interface{}) ([]byte, error)
JSONUnmarshal func(data []byte, v interface{}) error
// HeaderAuthorizationKey is used to set/access Request Authorization header
// value when `SetAuthToken` option is used.
HeaderAuthorizationKey string
// contains filtered or unexported fields
}
func New() *Client
// Creating client1
client1 := resty.New()
resp1, err1 := client1.R().Get("http://httpbin.org/get")
fmt.Println(resp1, err1)
// Creating client2
client2 := resty.New()
resp2, err2 := client2.R().Get("http://httpbin.org/get")
fmt.Println(resp2, err2)
func NewWithClient(hc http.Client) Client
func (c Client) AddRetryCondition(condition RetryConditionFunc) Client 增加重试策略
func (c Client) SetRetryAfter(callback RetryAfterFunc) Client
func (c Client) SetRetryCount(count int) Client 注意:这里的重试是针对client,req是依赖client发送的
func (c Client) SetRetryMaxWaitTime(maxWaitTime time.Duration) Client 默认2s
func (c Client) SetRetryWaitTime(waitTime time.Duration) Client 默认100ms
func (c Client) DisableTrace() Client 禁用追综
func (c Client) EnableTrace() Client 启用追综
func (c Client) GetClient() http.Client 获取一个client
func (c Client) IsProxySet() bool 是否设置了代理
func (c Client) RemoveProxy() Client 移除代理
func (c Client) SetProxy(proxyURL string) *Client
client.SetProxy("http://proxyserver:8888")
func (c Client) NewRequest() Request 新建一个request
func (c Client) R() Request 新建一个request
func (c Client) OnAfterResponse(m ResponseMiddleware) Client
client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
// Now you have access to Client and Response instance
// manipulate it as per your need
return nil // if its success otherwise return error
})
func (c Client) SetPreRequestHook(h PreRequestHook) Client 在request前调用,只能设置一个
func (c Client) OnBeforeRequest(m RequestMiddleware) Client
client.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error {
// Now you have access to Client and Request instance
// manipulate it as per your need
return nil // if its success otherwise return error
})
func (c Client) OnError(h ErrorHook) Client
OnError方法添加了一个回调函数,该函数将在请求执行失败时运行。在尝试了所有重试(如果有的话)之后调用。如果有来自服务器的响应,错误将被包装在*ResponseError中,其中包含从服务器接收到的最后一个响应。
client.OnError(func(req *resty.Request, err error) {
if v, ok := err.(*resty.ResponseError); ok {
// Do something with v.Response
}
// Log the error, increment a metric, etc...
})
func (c Client) OnRequestLog(rl RequestLogCallback) Client
func (c Client) OnResponseLog(rl ResponseLogCallback) Client
func (c Client) SetAuthScheme(scheme string) Client 设置认证方案
Authorization: <auth-scheme-value> <auth-token-value>
For Example: To set the scheme to use OAuth
client.SetAuthScheme("OAuth")
func (c Client) SetAuthToken(token string) Client
Authorization: <auth-scheme> <auth-token-value>
For Example: To set auth token BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F
client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F
func (c Client) SetBasicAuth(username, password string) Client
Authorization: Basic <base64-encoded-value>
For Example: To set the header for username "go-resty" and password "welcome"
client.SetBasicAuth("go-resty", "welcome")
func (c Client) SetCertificates(certs …tls.Certificate) Client
// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data.
cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
if err != nil {
log.Fatalf("ERROR client certificate: %s", err)
}
// Create a resty client
client := resty.New()
client.SetCertificates(cert)
func (c Client) SetContentLength(l bool) Client 是否需要设置Content-Length
func (c Client) SetCookie(hc http.Cookie) *Client
client.SetCookie(&http.Cookie{
Name:"go-resty",
Value:"This is cookie value",
})
func (c Client) SetCookieJar(jar http.CookieJar) Client
func (c Client) SetDebug(d bool) Client 调试模式
func (c Client) SetDoNotParseResponse(parse bool) Client 不自动解析response
- SetDoNotParseResponse方法指示’ Resty ‘不要自动解析响应体。Resty将原始响应体公开为’ io.ReadCloser ‘。也不要忘记关闭主体,否则可能会进入连接泄漏,没有连接重用。 注意:如果使用这个选项,响应中间件是不适用的。基本上,您已经从“Resty”接管了响应解析的控制权。
func (c Client) SetHeader(header, value string) Client
func (c Client) SetFormData(data map[string]string) Client
func (c Client) SetHeader(header, value string) Client
func (c Client) SetHeaders(headers map[string]string) Client
func (c Client) SetLogger(l Logger) Client
func (c Client) SetOutputDirectory(dirPath string) Client 设置下载的目录
client.SetOutputDirectory("/save/http/response/here")
func (c Client) SetPathParam(param, value string) Client
client.SetPathParam("userId", "sample@sample.com")
Result:
URL - /v1/users/{userId}/details
Composed URL - /v1/users/sample@sample.com/details
func (c Client) SetPathParams(params map[string]string) Client
client.SetPathParams(map[string]string{
"userId": "sample@sample.com",
"subAccountId": "100002",
})
Result:
URL - /v1/users/{userId}/{subAccountId}/details
Composed URL - /v1/users/sample@sample.com/100002/details
func (c Client) SetQueryParam(param, value string) Client
client.
SetQueryParam("search", "kitchen papers").
SetQueryParam("size", "large")
func (c Client) SetQueryParams(params map[string]string) Client
func (c Client) SetRedirectPolicy(policies …interface{}) Client 设置重定向策略
client.SetRedirectPolicy(FlexibleRedirectPolicy(20))
// Need multiple redirect policies together
client.SetRedirectPolicy(FlexibleRedirectPolicy(20), DomainCheckRedirectPolicy("host1.com", "host2.net"))
func (c Client) SetRootCertificate(pemFilePath string) Client
func (c Client) SetRootCertificateFromString(pemContent string) Client
client.SetRootCertificate("/path/to/root/pemFile.pem")
client.SetRootCertificateFromString("pem file content")
func (c Client) SetScheme(scheme string) Client
func (c Client) SetTLSClientConfig(config tls.Config) *Client
/ One can set custom root-certificate. Refer: http://golang.org/pkg/crypto/tls/#example_Dial
client.SetTLSClientConfig(&tls.Config{ RootCAs: roots })
// or One can disable security check (https)
client.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true })
func (c Client) SetTimeout(timeout time.Duration) Client
func (c Client) SetTransport(transport http.RoundTripper) Client
SetTransport方法设置自定义’ http。传输’或任何’ http。在rest客户端中兼容RoundTripper的接口实现。 注意: —如果传输类型不是http。然后你可能无法利用一些rest客户端设置。 它覆盖Resty客户端传输实例及其配置。
transport := &http.Transport{
// somthing like Proxying to httptest.Server, etc...
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
}
client.SetTransport(transport)
type ErrorHook
type ErrorHook func(*Request, error)
type Option
type Option func(*Options)
func MaxWaitTime(value time.Duration) Option 设置请求之间休眠的最大等待时间
func Retries(value int) Option
func RetryConditions(conditions []RetryConditionFunc) Option
func WaitTime(value time.Duration) Option
type Options
type Options struct {
// contains filtered or unexported fields
}
type Logger
type Logger interface {
Errorf(format string, v ...interface{})
Warnf(format string, v ...interface{})
Debugf(format string, v ...interface{})
}
type PreRequestHook
PreRequestHook类型用于请求钩子,在请求发送之前调用
type PreRequestHook func(*Client, *http.Request) error
type RedirectPolicy
RedirectPolicy用于规范rest客户端的重定向。实现RedirectPolicy接口的对象可以注册为 Apply函数返回nil以继续重定向,否则返回error以停止重定向。
type RedirectPolicy interface {
Apply(req *http.Request, via []*http.Request) error
}
// 重定向只允许策略中提供的hostname
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy
resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
// 重定向次数
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy
resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
// 不允许重试
func NoRedirectPolicy() RedirectPolicy
resty.SetRedirectPolicy(NoRedirectPolicy())
type RedirectPolicyFunc
RedirectPolicyFunc类型是一个适配器,允许使用普通函数作为RedirectPolicy。如果f是一个具有适当签名的函数,则RedirectPolicyFunc(f)是一个调用f的RedirectPolicy对象。
type RedirectPolicyFunc func(*http.Request, []*http.Request) error
func (f RedirectPolicyFunc) Apply(req http.Request, via []http.Request) error calls f(req, via)
type Request
type Request struct {
URL string
Method string
Token string
AuthScheme string
QueryParam url.Values
FormData url.Values
Header http.Header
Time time.Time
Body interface{}
Result interface{}
Error interface{}
RawRequest *http.Request
SRV *SRVRecord
UserInfo *User
Cookies []*http.Cookie
// Attempt is to represent the request attempt made during a Resty
// request execution flow, including retry count.
//
// Since v2.4.0
Attempt int
// contains filtered or unexported fields
}
func (r Request) Context() context.Context 如果有就返回,没有使用context.Background()新建
func (r Request) Delete(url string) (Response, error)
func (r Request) EnableTrace() Request
func (r Request) Execute(method, url string) (Response, error)
func (r Request) Get(url string) (Response, error)
func (r Request) Head(url string) (Response, error)
func (r Request) Options(url string) (Response, error)
func (r Request) Patch(url string) (Response, error)
func (r Request) Post(url string) (Response, error)
func (r Request) Put(url string) (Response, error)
func (r Request) Send() (Response, error)
func (r Request) SetAuthScheme(scheme string) Request 同client用法
func (r Request) SetAuthToken(token string) Request 同client用法
func (r Request) SetBasicAuth(username, password string) Request 同client用法
func (r Request) SetBody(body interface{}) Request
func (r Request) SetContentLength(l bool) Request
func (r Request) SetContext(ctx context.Context) Request
func (r Request) SetCookie(hc http.Cookie) Request
func (r Request) SetCookies(rs []http.Cookie) Request
func (r Request) SetDoNotParseResponse(parse bool) Request
func (r Request) SetFile(param, filePath string) *Request
client.R().
SetFile("my_file", "/Users/jeeva/Gas Bill - Sep.pdf")
func (r Request) SetFileReader(param, fileName string, reader io.Reader) Request
client.R().
SetFileReader("profile_img", "my-profile-img.png", bytes.NewReader(profileImgBytes)).
SetFileReader("notes", "user-notes.txt", bytes.NewReader(notesBytes))
func (r Request) SetFiles(files map[string]string) Request
client.R().
SetFiles(map[string]string{
"my_file1": "/Users/jeeva/Gas Bill - Sep.pdf",
"my_file2": "/Users/jeeva/Electricity Bill - Sep.pdf",
"my_file3": "/Users/jeeva/Water Bill - Sep.pdf",
})
func (r Request) SetFormData(data map[string]string) Request
// 自动将请求头content type 设置为 `application/x-www-form-urlencoded`
client.R().
SetFormData(map[string]string{
"access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F",
"user_id": "3455454545",
})
func (r Request) SetHeader(header, value string) Request
func (r Request) SetHeaders(headers map[string]string) Request
client.R().
SetHeaders(map[string]string{
"Content-Type": "application/json",
"Accept": "application/json",
})
func (r Request) SetMultipartField(param, fileName, contentType string, reader io.Reader) Request
func (r Request) SetMultipartFields(fields …MultipartField) *Request
client.R().SetMultipartFields(
&resty.MultipartField{
Param: "uploadManifest1",
FileName: "upload-file-1.json",
ContentType: "application/json",
Reader: strings.NewReader(`{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`),
},
&resty.MultipartField{
Param: "uploadManifest2",
FileName: "upload-file-2.json",
ContentType: "application/json",
Reader: strings.NewReader(`{"input": {"name": "Uploaded document 2", "_filename" : ["file2.txt"]}}`),
})
func (r Request) SetMultipartFormData(data map[string]string) Request
func (r Request) SetOutput(file string) Request 指定下载文件的绝对路径或相对路径(做目录使用)
client.R().
SetOutput("/Users/jeeva/Downloads/ReplyWithHeader-v5.1-beta.zip").
Get("http://bit.ly/1LouEKr")
func (r Request) SetPathParam(param, value string) Request
func (r Request) SetPathParams(params map[string]string) Request
client.R().SetPathParams(map[string]string{
"userId": "sample@sample.com",
"subAccountId": "100002",
})
Result:
URL - /v1/users/{userId}/{subAccountId}/details
Composed URL - /v1/users/sample@sample.com/100002/details
func (r Request) SetQueryParam(param, value string) Request
func (r Request) SetQueryParams(params map[string]string) Request
func (r Request) SetQueryParamsFromValues(params url.Values) Request
For Example: `status=pending&status=approved&status=open` in the URL after `?`
client.R().
SetQueryParamsFromValues(url.Values{
"status": []string{"pending", "approved", "open"},
})
func (r Request) SetQueryString(query string) Request
func (r *Request) TraceInfo() TraceInfo
type RequestLog
RequestLog结构用于从rest请求实例收集用于调试日志的信息。它在rest实际记录信息之前被发送到请求日志回调
type RequestLog struct {
Header http.Header
Body string
}
type RequestLogCallback
RequestLogCallback type用于请求日志,在记录请求之前调用
type RequestLogCallback func(*RequestLog) error
type RequestMiddleware
RequestMiddleware类型用于请求中间件,在请求发送之前调用
type RequestMiddleware func(*Client, *Request) error
type Response
响应结构保存已执行请求的响应值
type Response struct {
Request *Request
RawResponse *http.Response
// contains filtered or unexported fields
}
func (r Response) Body() []byte 如果使用了 Request.SetOutput
,它将是ni
func (r Response) Cookies() []http.Cookie
func (r Response) Error() interface{} 如果Error方法有一个Error对象,则返回该对象
func (r Response) Header() http.Header
func (r Response) IsError() bool 如果HTTP状态’ code >= 400 ‘,则IsError方法返回true,否则返回false
func (r Response) IsSuccess() bool 如果HTTP状态’ code >= 200 and <= 299 ‘否则返回true
func (r Response) Proto() string
func (r *Response) RawBody() io.ReadCloser
- RawBody方法公开HTTP原始响应体。使用这个方法结合’ SetDoNotParseResponse ‘选项,否则你会得到一个错误为’ read err: http: read on closed response body ‘。 不要忘记关闭阀体,否则可能会进入连接泄漏,没有连接重用。基本上,您已经从“Resty”接管了响应解析的控制权。
func (r Response) ReceivedAt() time.Time
func (r Response) Size() int64
func (r Response) Status() string Example: 200 OK
func (r Response) StatusCode() int Example: 200
func (r Response) String() string 以字符串的方式返回请求的响应
func (r Response) Time() time.Duration 请求的耗时
type ResponseError
type ResponseError struct {
Response *Response
Err error
}
func (e ResponseError) Error() string
func (e ResponseError) Unwrap() error
type ResponseLog
ResponseLog结构用于从rest响应实例收集调试日志信息。它在rest实际记录信息之前被发送到响应日志回调
type ResponseLog struct {
Header http.Header
Body string
}
type ResponseLogCallback
ResponseLogCallback类型用于响应日志,在记录响应之前调用
type ResponseLogCallback func(*ResponseLog) error
type ResponseMiddleware
ResponseMiddleware类型用于响应中间件,在收到响应后调用
type ResponseMiddleware func(*Client, *Response) error
type RetryAfterFunc
返回重试之前等待的时间,error不为nil,则终止重试
type RetryAfterFunc func(*Client, *Response) (time.Duration, error)
type RetryConditionFunc
控制重试
type RetryConditionFunc func(*Response, error) bool
type TraceInfo
type TraceInfo struct {
// DNSLookup is a duration that transport took to perform
// DNS lookup.
DNSLookup time.Duration
// ConnTime is a duration that took to obtain a successful connection.
ConnTime time.Duration
// TCPConnTime is a duration that took to obtain the TCP connection.
TCPConnTime time.Duration
// TLSHandshake is a duration that TLS handshake took place.
TLSHandshake time.Duration
// ServerTime is a duration that server took to respond first byte.
ServerTime time.Duration
// ResponseTime is a duration since first response byte from server to
// request completion.
ResponseTime time.Duration
// TotalTime is a duration that total request took end-to-end.
TotalTime time.Duration
// IsConnReused is whether this connection has been previously
// used for another HTTP request.
IsConnReused bool
// IsConnWasIdle is whether this connection was obtained from an
// idle pool.
IsConnWasIdle bool
// ConnIdleTime is a duration how long the connection was previously
// idle, if IsConnWasIdle is true.
ConnIdleTime time.Duration
// RequestAttempt is to represent the request attempt made during a Resty
// request execution flow, including retry count.
RequestAttempt int
// RemoteAddr returns the remote network address.
RemoteAddr net.Addr
}
type User
type User struct {
Username, Password string
}
小技巧
看源码中怎么关闭rsp.body的
defer closeq(rsp.body)
func closeq(v interface{}) {
if c, ok := v.(io.Closer); ok {
silently(c.Close())
}
}
func silently(_ ...interface{}) {}
一般的,我们是这么关闭的
defer rsp.body.Close()
这样写是不规范的,过不了代码检测,因为还没处理err
于是可以这样
defer func(){
_ = rsp.body.Close()
}()
很明显 代码到处这样写很丑