• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.testdata/H03-May-2022-

.gitignoreH A D01-Dec-2019339

.travis.ymlH A D01-Dec-2019353

BUILD.bazelH A D01-Dec-2019888

LICENSEH A D01-Dec-20191.1 KiB

README.mdH A D01-Dec-201929 KiB

WORKSPACEH A D01-Dec-2019527

client.goH A D01-Dec-201929.3 KiB

client_test.goH A D01-Dec-201914.6 KiB

context_test.goH A D01-Dec-20195.1 KiB

example_test.goH A D01-Dec-20196.1 KiB

go.modH A D01-Dec-201997

middleware.goH A D01-Dec-201912.6 KiB

redirect.goH A D01-Dec-20193.5 KiB

request.goH A D01-Dec-201923.1 KiB

request_test.goH A D01-Dec-201938.4 KiB

response.goH A D01-Dec-20194.8 KiB

resty.goH A D01-Dec-20191.1 KiB

resty_test.goH A D01-Dec-201918.7 KiB

retry.goH A D01-Dec-20194.1 KiB

retry_test.goH A D01-Dec-201915.8 KiB

trace.goH A D01-Dec-20193.6 KiB

util.goH A D01-Dec-20198.5 KiB

util_test.goH A D01-Dec-20191.9 KiB

README.md

1<p align="center">
2<h1 align="center">Resty</h1>
3<p align="center">Simple HTTP and REST client library for Go (inspired by Ruby rest-client)</p>
4<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
5</p>
6<p align="center">
7<p align="center"><a href="https://travis-ci.org/go-resty/resty"><img src="https://travis-ci.org/go-resty/resty.svg?branch=master" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.1.0-blue.svg" alt="Release Version"></a> <a href="https://godoc.org/github.com/go-resty/resty"><img src="https://godoc.org/github.com/go-resty/resty?status.svg" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
8</p>
9<p align="center">
10<h4 align="center">Resty Communication Channels</h4>
11<p align="center"><a href="https://gitter.im/go_resty/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/go_resty/community.svg" alt="Chat on Gitter - Resty Community"></a> <a href="https://twitter.com/go_resty"><img src="https://img.shields.io/badge/twitter-@go__resty-55acee.svg" alt="Twitter @go_resty"></a></p>
12</p>
13
14## News
15
16  * v2.1.0 [released](https://github.com/go-resty/resty/releases/tag/v2.1.0) and tagged on Oct 10, 2019.
17  * v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
18  * v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
19  * v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
20
21## Features
22
23  * GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc.
24  * Simple and chainable methods for settings and request
25  * [Request](https://godoc.org/github.com/go-resty/resty#Request) Body can be `string`, `[]byte`, `struct`, `map`, `slice` and `io.Reader` too
26    * Auto detects `Content-Type`
27    * Buffer less processing for `io.Reader`
28    * Request Body can be read multiple times via `Request.RawRequest.GetBody()`
29  * [Response](https://godoc.org/github.com/go-resty/resty#Response) object gives you more possibility
30    * Access as `[]byte` array - `response.Body()` OR Access as `string` - `response.String()`
31    * Know your `response.Time()` and when we `response.ReceivedAt()`
32  * Automatic marshal and unmarshal for `JSON` and `XML` content type
33    * Default is `JSON`, if you supply `struct/map` without header `Content-Type`
34    * For auto-unmarshal, refer to -
35        - Success scenario [Request.SetResult()](https://godoc.org/github.com/go-resty/resty#Request.SetResult) and [Response.Result()](https://godoc.org/github.com/go-resty/resty#Response.Result).
36        - Error scenario [Request.SetError()](https://godoc.org/github.com/go-resty/resty#Request.SetError) and [Response.Error()](https://godoc.org/github.com/go-resty/resty#Response.Error).
37        - Supports [RFC7807](https://tools.ietf.org/html/rfc7807) - `application/problem+json` & `application/problem+xml`
38  * Easy to upload one or more file(s) via `multipart/form-data`
39    * Auto detects file content type
40  * Request URL [Path Params (aka URI Params)](https://godoc.org/github.com/go-resty/resty#Request.SetPathParams)
41  * Backoff Retry Mechanism with retry condition function [reference](retry_test.go)
42  * Resty client HTTP & REST [Request](https://godoc.org/github.com/go-resty/resty#Client.OnBeforeRequest) and [Response](https://godoc.org/github.com/go-resty/resty#Client.OnAfterResponse) middlewares
43  * `Request.SetContext` supported
44  * Authorization option of `BasicAuth` and `Bearer` token
45  * Set request `ContentLength` value for all request or particular request
46  * Custom [Root Certificates](https://godoc.org/github.com/go-resty/resty#Client.SetRootCertificate) and Client [Certificates](https://godoc.org/github.com/go-resty/resty#Client.SetCertificates)
47  * Download/Save HTTP response directly into File, like `curl -o` flag. See [SetOutputDirectory](https://godoc.org/github.com/go-resty/resty#Client.SetOutputDirectory) & [SetOutput](https://godoc.org/github.com/go-resty/resty#Request.SetOutput).
48  * Cookies for your request and CookieJar support
49  * SRV Record based request instead of Host URL
50  * Client settings like `Timeout`, `RedirectPolicy`, `Proxy`, `TLSClientConfig`, `Transport`, etc.
51  * Optionally allows GET request with payload, see [SetAllowGetMethodPayload](https://godoc.org/github.com/go-resty/resty#Client.SetAllowGetMethodPayload)
52  * Supports registering external JSON library into resty, see [how to use](https://github.com/go-resty/resty/issues/76#issuecomment-314015250)
53  * Exposes Response reader without reading response (no auto-unmarshaling) if need be, see [how to use](https://github.com/go-resty/resty/issues/87#issuecomment-322100604)
54  * Option to specify expected `Content-Type` when response `Content-Type` header missing. Refer to [#92](https://github.com/go-resty/resty/issues/92)
55  * Resty design
56    * Have client level settings & options and also override at Request level if you want to
57    * Request and Response middlewares
58    * Create Multiple clients if you want to `resty.New()`
59    * Supports `http.RoundTripper` implementation, see [SetTransport](https://godoc.org/github.com/go-resty/resty#Client.SetTransport)
60    * goroutine concurrent safe
61    * Resty Client trace, see [Client.EnableTrace](https://godoc.org/github.com/go-resty/resty#Client.EnableTrace) and [Request.EnableTrace](https://godoc.org/github.com/go-resty/resty#Request.EnableTrace)
62    * Debug mode - clean and informative logging presentation
63    * Gzip - Go does it automatically also resty has fallback handling too
64    * Works fine with `HTTP/2` and `HTTP/1.1`
65  * [Bazel support](#bazel-support)
66  * Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library)
67  * Well tested client library
68
69### Included Batteries
70
71  * Redirect Policies - see [how to use](#redirect-policy)
72    * NoRedirectPolicy
73    * FlexibleRedirectPolicy
74    * DomainCheckRedirectPolicy
75    * etc. [more info](redirect.go)
76  * Retry Mechanism [how to use](#retries)
77    * Backoff Retry
78    * Conditional Retry
79  * SRV Record based request instead of Host URL [how to use](resty_test.go#L1412)
80  * etc (upcoming - throw your idea's [here](https://github.com/go-resty/resty/issues)).
81
82
83#### Supported Go Versions
84
85Initially Resty started supporting `go modules` since `v1.10.0` release.
86
87Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
88
89- 1.9.7+
90- 1.10.3+
91- 1.11+
92
93
94## It might be beneficial for your project :smile:
95
96Resty author also published following projects for Go Community.
97
98  * [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework.
99  * [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server.
100  * [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`.
101
102
103## Installation
104
105```bash
106# Go Modules
107require github.com/go-resty/resty/v2 v2.1.0
108```
109
110## Usage
111
112The following samples will assist you to become as comfortable as possible with resty library.
113
114```go
115// Import resty into your code and refer it as `resty`.
116import "github.com/go-resty/resty/v2"
117```
118
119#### Simple GET
120
121```go
122// Create a Resty Client
123client := resty.New()
124
125resp, err := client.R().
126		EnableTrace().
127		Get("https://httpbin.org/get")
128
129// Explore response object
130fmt.Println("Response Info:")
131fmt.Println("Error      :", err)
132fmt.Println("Status Code:", resp.StatusCode())
133fmt.Println("Status     :", resp.Status())
134fmt.Println("Time       :", resp.Time())
135fmt.Println("Received At:", resp.ReceivedAt())
136fmt.Println("Body       :\n", resp)
137fmt.Println()
138
139// Explore trace info
140fmt.Println("Request Trace Info:")
141ti := resp.Request.TraceInfo()
142fmt.Println("DNSLookup    :", ti.DNSLookup)
143fmt.Println("ConnTime     :", ti.ConnTime)
144fmt.Println("TLSHandshake :", ti.TLSHandshake)
145fmt.Println("ServerTime   :", ti.ServerTime)
146fmt.Println("ResponseTime :", ti.ResponseTime)
147fmt.Println("TotalTime    :", ti.TotalTime)
148fmt.Println("IsConnReused :", ti.IsConnReused)
149fmt.Println("IsConnWasIdle:", ti.IsConnWasIdle)
150fmt.Println("ConnIdleTime :", ti.ConnIdleTime)
151
152/* Output
153Response Info:
154Error      : <nil>
155Status Code: 200
156Status     : 200 OK
157Time       : 465.301137ms
158Received At: 2019-06-16 01:52:33.772456 -0800 PST m=+0.466672260
159Body       :
160 {
161  "args": {},
162  "headers": {
163    "Accept-Encoding": "gzip",
164    "Host": "httpbin.org",
165    "User-Agent": "go-resty/2.0.0 (https://github.com/go-resty/resty)"
166  },
167  "origin": "0.0.0.0",
168  "url": "https://httpbin.org/get"
169}
170
171Request Trace Info:
172DNSLookup    : 2.21124ms
173ConnTime     : 393.875795ms
174TLSHandshake : 319.313546ms
175ServerTime   : 71.109256ms
176ResponseTime : 94.466µs
177TotalTime    : 465.301137ms
178IsConnReused : false
179IsConnWasIdle: false
180ConnIdleTime : 0s
181*/
182```
183
184#### Enhanced GET
185
186```go
187// Create a Resty Client
188client := resty.New()
189
190resp, err := client.R().
191      SetQueryParams(map[string]string{
192          "page_no": "1",
193          "limit": "20",
194          "sort":"name",
195          "order": "asc",
196          "random":strconv.FormatInt(time.Now().Unix(), 10),
197      }).
198      SetHeader("Accept", "application/json").
199      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
200      Get("/search_result")
201
202
203// Sample of using Request.SetQueryString method
204resp, err := client.R().
205      SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
206      SetHeader("Accept", "application/json").
207      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
208      Get("/show_product")
209```
210
211#### Various POST method combinations
212
213```go
214// Create a Resty Client
215client := resty.New()
216
217// POST JSON string
218// No need to set content type, if you have client level setting
219resp, err := client.R().
220      SetHeader("Content-Type", "application/json").
221      SetBody(`{"username":"testuser", "password":"testpass"}`).
222      SetResult(&AuthSuccess{}).    // or SetResult(AuthSuccess{}).
223      Post("https://myapp.com/login")
224
225// POST []byte array
226// No need to set content type, if you have client level setting
227resp, err := client.R().
228      SetHeader("Content-Type", "application/json").
229      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
230      SetResult(&AuthSuccess{}).    // or SetResult(AuthSuccess{}).
231      Post("https://myapp.com/login")
232
233// POST Struct, default is JSON content type. No need to set one
234resp, err := client.R().
235      SetBody(User{Username: "testuser", Password: "testpass"}).
236      SetResult(&AuthSuccess{}).    // or SetResult(AuthSuccess{}).
237      SetError(&AuthError{}).       // or SetError(AuthError{}).
238      Post("https://myapp.com/login")
239
240// POST Map, default is JSON content type. No need to set one
241resp, err := client.R().
242      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
243      SetResult(&AuthSuccess{}).    // or SetResult(AuthSuccess{}).
244      SetError(&AuthError{}).       // or SetError(AuthError{}).
245      Post("https://myapp.com/login")
246
247// POST of raw bytes for file upload. For example: upload file to Dropbox
248fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf")
249
250// See we are not setting content-type header, since go-resty automatically detects Content-Type for you
251resp, err := client.R().
252      SetBody(fileBytes).
253      SetContentLength(true).          // Dropbox expects this value
254      SetAuthToken("<your-auth-token>").
255      SetError(&DropboxError{}).       // or SetError(DropboxError{}).
256      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // for upload Dropbox supports PUT too
257
258// Note: resty detects Content-Type for request body/payload if content type header is not set.
259//   * For struct and map data type defaults to 'application/json'
260//   * Fallback is plain text content type
261```
262
263#### Sample PUT
264
265You can use various combinations of `PUT` method call like demonstrated for `POST`.
266
267```go
268// Note: This is one sample of PUT method usage, refer POST for more combination
269
270// Create a Resty Client
271client := resty.New()
272
273// Request goes as JSON content type
274// No need to set auth token, error, if you have client level settings
275resp, err := client.R().
276      SetBody(Article{
277        Title: "go-resty",
278        Content: "This is my article content, oh ya!",
279        Author: "Jeevanandam M",
280        Tags: []string{"article", "sample", "resty"},
281      }).
282      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
283      SetError(&Error{}).       // or SetError(Error{}).
284      Put("https://myapp.com/article/1234")
285```
286
287#### Sample PATCH
288
289You can use various combinations of `PATCH` method call like demonstrated for `POST`.
290
291```go
292// Note: This is one sample of PUT method usage, refer POST for more combination
293
294// Create a Resty Client
295client := resty.New()
296
297// Request goes as JSON content type
298// No need to set auth token, error, if you have client level settings
299resp, err := client.R().
300      SetBody(Article{
301        Tags: []string{"new tag1", "new tag2"},
302      }).
303      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
304      SetError(&Error{}).       // or SetError(Error{}).
305      Patch("https://myapp.com/articles/1234")
306```
307
308#### Sample DELETE, HEAD, OPTIONS
309
310```go
311// Create a Resty Client
312client := resty.New()
313
314// DELETE a article
315// No need to set auth token, error, if you have client level settings
316resp, err := client.R().
317      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
318      SetError(&Error{}).       // or SetError(Error{}).
319      Delete("https://myapp.com/articles/1234")
320
321// DELETE a articles with payload/body as a JSON string
322// No need to set auth token, error, if you have client level settings
323resp, err := client.R().
324      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
325      SetError(&Error{}).       // or SetError(Error{}).
326      SetHeader("Content-Type", "application/json").
327      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
328      Delete("https://myapp.com/articles")
329
330// HEAD of resource
331// No need to set auth token, if you have client level settings
332resp, err := client.R().
333      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
334      Head("https://myapp.com/videos/hi-res-video")
335
336// OPTIONS of resource
337// No need to set auth token, if you have client level settings
338resp, err := client.R().
339      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
340      Options("https://myapp.com/servers/nyc-dc-01")
341```
342
343### Multipart File(s) upload
344
345#### Using io.Reader
346
347```go
348profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png")
349notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt")
350
351// Create a Resty Client
352client := resty.New()
353
354resp, err := client.R().
355      SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
356      SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
357      SetFormData(map[string]string{
358          "first_name": "Jeevanandam",
359          "last_name": "M",
360      }).
361      Post("http://myapp.com/upload")
362```
363
364#### Using File directly from Path
365
366```go
367// Create a Resty Client
368client := resty.New()
369
370// Single file scenario
371resp, err := client.R().
372      SetFile("profile_img", "/Users/jeeva/test-img.png").
373      Post("http://myapp.com/upload")
374
375// Multiple files scenario
376resp, err := client.R().
377      SetFiles(map[string]string{
378        "profile_img": "/Users/jeeva/test-img.png",
379        "notes": "/Users/jeeva/text-file.txt",
380      }).
381      Post("http://myapp.com/upload")
382
383// Multipart of form fields and files
384resp, err := client.R().
385      SetFiles(map[string]string{
386        "profile_img": "/Users/jeeva/test-img.png",
387        "notes": "/Users/jeeva/text-file.txt",
388      }).
389      SetFormData(map[string]string{
390        "first_name": "Jeevanandam",
391        "last_name": "M",
392        "zip_code": "00001",
393        "city": "my city",
394        "access_token": "C6A79608-782F-4ED0-A11D-BD82FAD829CD",
395      }).
396      Post("http://myapp.com/profile")
397```
398
399#### Sample Form submission
400
401```go
402// Create a Resty Client
403client := resty.New()
404
405// just mentioning about POST as an example with simple flow
406// User Login
407resp, err := client.R().
408      SetFormData(map[string]string{
409        "username": "jeeva",
410        "password": "mypass",
411      }).
412      Post("http://myapp.com/login")
413
414// Followed by profile update
415resp, err := client.R().
416      SetFormData(map[string]string{
417        "first_name": "Jeevanandam",
418        "last_name": "M",
419        "zip_code": "00001",
420        "city": "new city update",
421      }).
422      Post("http://myapp.com/profile")
423
424// Multi value form data
425criteria := url.Values{
426  "search_criteria": []string{"book", "glass", "pencil"},
427}
428resp, err := client.R().
429      SetFormDataFromValues(criteria).
430      Post("http://myapp.com/search")
431```
432
433#### Save HTTP Response into File
434
435```go
436// Create a Resty Client
437client := resty.New()
438
439// Setting output directory path, If directory not exists then resty creates one!
440// This is optional one, if you're planning using absoule path in
441// `Request.SetOutput` and can used together.
442client.SetOutputDirectory("/Users/jeeva/Downloads")
443
444// HTTP response gets saved into file, similar to curl -o flag
445_, err := client.R().
446          SetOutput("plugin/ReplyWithHeader-v5.1-beta.zip").
447          Get("http://bit.ly/1LouEKr")
448
449// OR using absolute path
450// Note: output directory path is not used for absoulte path
451_, err := client.R().
452          SetOutput("/MyDownloads/plugin/ReplyWithHeader-v5.1-beta.zip").
453          Get("http://bit.ly/1LouEKr")
454```
455
456#### Request URL Path Params
457
458Resty provides easy to use dynamic request URL path params. Params can be set at client and request level. Client level params value can be overridden at request level.
459
460```go
461// Create a Resty Client
462client := resty.New()
463
464client.R().SetPathParams(map[string]string{
465   "userId": "sample@sample.com",
466   "subAccountId": "100002",
467}).
468Get("/v1/users/{userId}/{subAccountId}/details")
469
470// Result:
471//   Composed URL - /v1/users/sample@sample.com/100002/details
472```
473
474#### Request and Response Middleware
475
476Resty provides middleware ability to manipulate for Request and Response. It is more flexible than callback approach.
477
478```go
479// Create a Resty Client
480client := resty.New()
481
482// Registering Request Middleware
483client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
484    // Now you have access to Client and current Request object
485    // manipulate it as per your need
486
487    return nil  // if its success otherwise return error
488  })
489
490// Registering Response Middleware
491client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
492    // Now you have access to Client and current Response object
493    // manipulate it as per your need
494
495    return nil  // if its success otherwise return error
496  })
497```
498
499#### Redirect Policy
500
501Resty provides few ready to use redirect policy(s) also it supports multiple policies together.
502
503```go
504// Create a Resty Client
505client := resty.New()
506
507// Assign Client Redirect Policy. Create one as per you need
508client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(15))
509
510// Wanna multiple policies such as redirect count, domain name check, etc
511client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(20),
512                        resty.DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
513```
514
515##### Custom Redirect Policy
516
517Implement [RedirectPolicy](redirect.go#L20) interface and register it with resty client. Have a look [redirect.go](redirect.go) for more information.
518
519```go
520// Create a Resty Client
521client := resty.New()
522
523// Using raw func into resty.SetRedirectPolicy
524client.SetRedirectPolicy(resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
525  // Implement your logic here
526
527  // return nil for continue redirect otherwise return error to stop/prevent redirect
528  return nil
529}))
530
531//---------------------------------------------------
532
533// Using struct create more flexible redirect policy
534type CustomRedirectPolicy struct {
535  // variables goes here
536}
537
538func (c *CustomRedirectPolicy) Apply(req *http.Request, via []*http.Request) error {
539  // Implement your logic here
540
541  // return nil for continue redirect otherwise return error to stop/prevent redirect
542  return nil
543}
544
545// Registering in resty
546client.SetRedirectPolicy(CustomRedirectPolicy{/* initialize variables */})
547```
548
549#### Custom Root Certificates and Client Certificates
550
551```go
552// Create a Resty Client
553client := resty.New()
554
555// Custom Root certificates, just supply .pem file.
556// you can add one or more root certificates, its get appended
557client.SetRootCertificate("/path/to/root/pemFile1.pem")
558client.SetRootCertificate("/path/to/root/pemFile2.pem")
559// ... and so on!
560
561// Adding Client Certificates, you add one or more certificates
562// Sample for creating certificate object
563// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data.
564cert1, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
565if err != nil {
566  log.Fatalf("ERROR client certificate: %s", err)
567}
568// ...
569
570// You add one or more certificates
571client.SetCertificates(cert1, cert2, cert3)
572```
573
574#### Proxy Settings - Client as well as at Request Level
575
576Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`.
577Choose as per your need.
578
579**Client Level Proxy** settings applied to all the request
580
581```go
582// Create a Resty Client
583client := resty.New()
584
585// Setting a Proxy URL and Port
586client.SetProxy("http://proxyserver:8888")
587
588// Want to remove proxy setting
589client.RemoveProxy()
590```
591
592#### Retries
593
594Resty uses [backoff](http://www.awsarchitectureblog.com/2015/03/backoff.html)
595to increase retry intervals after each attempt.
596
597Usage example:
598
599```go
600// Create a Resty Client
601client := resty.New()
602
603// Retries are configured per client
604client.
605    // Set retry count to non zero to enable retries
606    SetRetryCount(3).
607    // You can override initial retry wait time.
608    // Default is 100 milliseconds.
609    SetRetryWaitTime(5 * time.Second).
610    // MaxWaitTime can be overridden as well.
611    // Default is 2 seconds.
612    SetRetryMaxWaitTime(20 * time.Second).
613    // SetRetryAfter sets callback to calculate wait time between retries.
614    // Default (nil) implies exponential backoff with jitter
615    SetRetryAfter(func(client *Client, resp *Response) (time.Duration, error) {
616        return 0, errors.New("quota exceeded")
617    })
618```
619
620Above setup will result in resty retrying requests returned non nil error up to
6213 times with delay increased after each attempt.
622
623You can optionally provide client with custom retry conditions:
624
625```go
626// Create a Resty Client
627client := resty.New()
628
629client.AddRetryCondition(
630    // RetryConditionFunc type is for retry condition function
631	  // input: non-nil Response OR request execution error
632    func(r *resty.Response, err error) bool {
633        return r.StatusCode() == http.StatusTooManyRequests
634    },
635)
636```
637
638Above example will make resty retry requests ended with `429 Too Many Requests`
639status code.
640
641Multiple retry conditions can be added.
642
643It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios
644implemented. [Reference](retry_test.go).
645
646#### Allow GET request with Payload
647
648```go
649// Create a Resty Client
650client := resty.New()
651
652// Allow GET request with Payload. This is disabled by default.
653client.SetAllowGetMethodPayload(true)
654```
655
656#### Wanna Multiple Clients
657
658```go
659// Here you go!
660// Client 1
661client1 := resty.New()
662client1.R().Get("http://httpbin.org")
663// ...
664
665// Client 2
666client2 := resty.New()
667client2.R().Head("http://httpbin.org")
668// ...
669
670// Bend it as per your need!!!
671```
672
673#### Remaining Client Settings & its Options
674
675```go
676// Create a Resty Client
677client := resty.New()
678
679// Unique settings at Client level
680//--------------------------------
681// Enable debug mode
682client.SetDebug(true)
683
684// Assign Client TLSClientConfig
685// One can set custom root-certificate. Refer: http://golang.org/pkg/crypto/tls/#example_Dial
686client.SetTLSClientConfig(&tls.Config{ RootCAs: roots })
687
688// or One can disable security check (https)
689client.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true })
690
691// Set client timeout as per your need
692client.SetTimeout(1 * time.Minute)
693
694
695// You can override all below settings and options at request level if you want to
696//--------------------------------------------------------------------------------
697// Host URL for all request. So you can use relative URL in the request
698client.SetHostURL("http://httpbin.org")
699
700// Headers for all request
701client.SetHeader("Accept", "application/json")
702client.SetHeaders(map[string]string{
703        "Content-Type": "application/json",
704        "User-Agent": "My custom User Agent String",
705      })
706
707// Cookies for all request
708client.SetCookie(&http.Cookie{
709      Name:"go-resty",
710      Value:"This is cookie value",
711      Path: "/",
712      Domain: "sample.com",
713      MaxAge: 36000,
714      HttpOnly: true,
715      Secure: false,
716    })
717client.SetCookies(cookies)
718
719// URL query parameters for all request
720client.SetQueryParam("user_id", "00001")
721client.SetQueryParams(map[string]string{ // sample of those who use this manner
722      "api_key": "api-key-here",
723      "api_secert": "api-secert",
724    })
725client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
726
727// Form data for all request. Typically used with POST and PUT
728client.SetFormData(map[string]string{
729    "access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F",
730  })
731
732// Basic Auth for all request
733client.SetBasicAuth("myuser", "mypass")
734
735// Bearer Auth Token for all request
736client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F")
737
738// Enabling Content length value for all request
739client.SetContentLength(true)
740
741// Registering global Error object structure for JSON/XML request
742client.SetError(&Error{})    // or resty.SetError(Error{})
743```
744
745#### Unix Socket
746
747```go
748unixSocket := "/var/run/my_socket.sock"
749
750// Create a Go's http.Transport so we can set it in resty.
751transport := http.Transport{
752	Dial: func(_, _ string) (net.Conn, error) {
753		return net.Dial("unix", unixSocket)
754	},
755}
756
757// Create a Resty Client
758client := resty.New()
759
760// Set the previous transport that we created, set the scheme of the communication to the
761// socket and set the unixSocket as the HostURL.
762client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket)
763
764// No need to write the host's URL on the request, just the path.
765client.R().Get("/index.html")
766```
767
768#### Bazel support
769
770Resty can be built, tested and depended upon via [Bazel](https://bazel.build).
771For example, to run all tests:
772
773```shell
774bazel test :go_default_test
775```
776
777#### Mocking http requests using [httpmock](https://github.com/jarcoal/httpmock) library
778
779In order to mock the http requests when testing your application you
780could use the `httpmock` library.
781
782When using the default resty client, you should pass the client to the library as follow:
783
784```go
785// Create a Resty Client
786client := resty.New()
787
788// Get the underlying HTTP Client and set it to Mock
789httpmock.ActivateNonDefault(client.GetClient())
790```
791
792More detailed example of mocking resty http requests using ginko could be found [here](https://github.com/jarcoal/httpmock#ginkgo--resty-example).
793
794## Versioning
795
796Resty releases versions according to [Semantic Versioning](http://semver.org)
797
798  * Resty v2 does not use `gopkg.in` service for library versioning.
799  * Resty fully adapted to `go mod` capabilities since `v1.10.0` release.
800  * Resty v1 series was using `gopkg.in` to provide versioning. `gopkg.in/resty.vX` points to appropriate tagged versions; `X` denotes version series number and it's a stable release for production use. For e.g. `gopkg.in/resty.v0`.
801  * Development takes place at the master branch. Although the code in master should always compile and test successfully, it might break API's. I aim to maintain backwards compatibility, but sometimes API's and behavior might be changed to fix a bug.
802
803## Contribution
804
805I would welcome your contribution! If you find any improvement or issue you want to fix, feel free to send a pull request, I like pull requests that include test cases for fix/enhancement. I have done my best to bring pretty good code coverage. Feel free to write tests.
806
807BTW, I'd like to know what you think about `Resty`. Kindly open an issue or send me an email; it'd mean a lot to me.
808
809## Creator
810
811[Jeevanandam M.](https://github.com/jeevatkm) (jeeva@myjeeva.com)
812
813## Contributors
814
815Have a look on [Contributors](https://github.com/go-resty/resty/graphs/contributors) page.
816
817## License
818
819Resty released under MIT license, refer [LICENSE](LICENSE) file.
820