## 1. Project Overview & Quickstart (go-resty/resty)

## Documentation

Go to https://resty.dev and refer to godoc.

## Minimum Go Version

Use `go1.23` and above.

## Support & Donate

* Sponsor via [GitHub](https://github.com/sponsors/jeevatkm)
* Donate via [PayPal](https://www.paypal.com/donate/?cmd=_donations&business=QWMZG74FW4QYC&lc=US&item_name=Resty+Library+for+Go&currency_code=USD)

## Versioning

Resty releases versions according to [Semantic Versioning](http://semver.org)

  * Resty v3 provides Go Vanity URL `resty.dev/v3`.
  * Resty v2 migrated away from `gopkg.in` service, `github.com/go-resty/resty/v2`.
  * Resty fully adapted to `go mod` capabilities since `v1.10.0` release.
  * 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`.

## Contribution

I would welcome your contribution!

* If you find any improvement or issue you want to fix, feel free to send a pull request.
* The pull requests must include test cases for feature/fix/enhancement with patch coverage of 100%.
* I have done my best to bring pretty good coverage. I would request contributors to do the same for their contribution.

I always look forward to hearing feedback, appreciation, and real-world usage stories from Resty users on [GitHub Discussions](https://github.com/go-resty/resty/discussions). It means a lot to me.

## Creator

[Jeevanandam M.](https://github.com/jeevatkm) (jeeva@myjeeva.com)


## Contributors

Have a look on [Contributors](https://github.com/go-resty/resty/graphs/contributors) page.

## License Info

Resty released under MIT [LICENSE](LICENSE).

Resty [Documentation](https://github.com/go-resty/docs) and website released under Apache-2.0 [LICENSE](https://github.com/go-resty/docs/blob/main/LICENSE).

## 2. Official Technical Reference & Guides (go-resty/docs)

## File: README.md

# Documentation

Go to https://resty.dev and refer to godoc.

## Contribution

I would welcome your contribution! If you find any improvement, correction, or want to add new documentation pages, feel free to send a pull request.

### Run Documentation Website Locally

Resty uses the Hugo static site generator. It requires v0.146 and above.

```shell
hugo server --minify
```

Go to http://localhost:1313/ to see the documentation website.

## Contributors

Have a look on [Contributors](https://github.com/go-resty/docs/graphs/contributors) page.

## License Info

Resty [Documentation](https://github.com/go-resty/docs) and website released under Apache-2.0 [LICENSE](LICENSE).

---

## File: content/docs/example/custom-dns-resolver.md

# Custom DNS Resolver

Resty v3 introduces additional methods for creating client instances, including the [NewWithDialer]({{% godoc v3 %}}NewWithDialer) function.

```go
package main

import (
	"context"
	"fmt"
	"net"
	"time"

	"resty.dev/v3"
)

func main() {
	dialer := &net.Dialer{
		Resolver: &net.Resolver{
			PreferGo: true,
			Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
				d := net.Dialer{
					Timeout: time.Duration(20) * time.Second,
				}
				return d.DialContext(ctx, "udp", "9.9.9.9:53") // Quad9 DNS
			},
		},
	}

	c := resty.NewWithDialer(dialer)
	defer c.Close()

	res, err := c.R().Get("https://httpbin.org/get")
	fmt.Println(err, res)
}
```

---

## File: content/docs/example/decompress-brotli.md

# Brotli Decompress

Resty v3 allows users to add decompression logic for HTTP responses using their favorite package.

> [!NOTE]
> Using `sync.Pool` can reuse the reader and reduce allocation if the package supports `Reset`.

## Example 1

Package: [github.com/andybalholm/brotli](https://github.com/andybalholm/brotli)

[](https://pkg.go.dev/github.com/andybalholm/brotli)

```go
c := resty.New()
defer c.Close()

// Add decompresser into Resty
client.AddContentDecompresser("br", decompressBrotli)

// Create Brotli decompress logic
func decompressBrotli(r io.ReadCloser) (io.ReadCloser, error) {
	br := &brotliReader{s: r, r: brotli.NewReader(r)}
	return br, nil
}

type brotliReader struct {
	s io.ReadCloser
	r *brotli.Reader
}

func (b *brotliReader) Read(p []byte) (n int, err error) {
	return b.r.Read(p)
}

func (b *brotliReader) Close() error {
	return b.s.Close()
}
```

## Example 2

Package: [github.com/dsnet/compress](https://github.com/dsnet/compress)

[](https://pkg.go.dev/github.com/dsnet/compress/brotli)

```go
c := resty.New()
defer c.Close()

// Add decompresser into Resty
client.AddContentDecompresser("br", decompressBrotli)

// Create Brotli decompress logic
func decompressBrotli(r io.ReadCloser) (io.ReadCloser, error) {
	br, err := brotli.NewReader(r, nil)
	if err != nil {
		return nil, err
	}
	b := &brotliReader{s: r, r: br}
	return b, nil
}

type brotliReader struct {
	s io.ReadCloser
	r *brotli.Reader
}

func (b *brotliReader) Read(p []byte) (n int, err error) {
	return b.r.Read(p)
}

func (b *brotliReader) Close() error {
	_ = b.r.Close()
	return b.s.Close()
}
```

---

## File: content/docs/example/decompress-zstandard.md

# Zstandard Decompress

Resty v3 allows users to add decompression logic for HTTP responses using their favorite package.

> [!NOTE]
> Using `sync.Pool` can reuse the reader and reduce allocation if the package supports `Reset`.

## Example

Package: [github.com/klauspost/compress/zstd](https://github.com/klauspost/compress)

[](https://pkg.go.dev/github.com/klauspost/compress/zstd)

```go
c := resty.New()
defer c.Close()

// Add decompresser into Resty
client.AddContentDecompresser("zstd", decompressZstd)

// Create Zstandard decompress logic
func decompressZstd(r io.ReadCloser) (io.ReadCloser, error) {
	zr, err := zstd.NewReader(r)
	if err != nil {
		return nil, err
	}
	z := &zstdReader{s: r, r: zr}
	return z, nil
}

type zstdReader struct {
	s io.ReadCloser
	r *zstd.Decoder
}

func (b *zstdReader) Read(p []byte) (n int, err error) {
	return b.r.Read(p)
}

func (b *zstdReader) Close() error {
	b.r.Close()
	return b.s.Close()
}
```

---

## File: content/docs/example/delete-request.md

---
title: DELETE Request
weight: 2
---

# DELETE Request

This page discusses simple DELETE requests. Resty features can be used across nearly all HTTP methods.

> [!NOTE]
> * Explore the documentation for additional use cases.
> * Examples use request-level methods; however, Resty also includes client-level methods to configure settings for all requests.

## Examples

See [Request Body Types]({{% relref "request-body-types" %}}), [Allow Payload On]({{% relref "allow-payload-on" %}})

```go
// create a Resty client
client := resty.New()
defer client.Close()
```

### Simple

```go
res, err := client.R().
    SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
    SetResultError(&Error{}). // or SetResultError(Error{}).
    Delete("https://myapp.com/articles/123456")

fmt.Println(err, res)
fmt.Println(res.ResultError().(*Error))
```

### With Payload

See [Allow Payload On]({{% relref "allow-payload-on" %}})

```go
res, err := client.R().
    SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
    SetBody(map[string]any{
        "article_ids": []int{1002, 1006, 1007, 87683, 45432},
    }). // default request content type is JSON
    SetResultError(&Error{}). // or SetResultError(Error{}).
    Delete("https://myapp.com/articles")

fmt.Println(err, res)
fmt.Println(res.ResultError().(*Error))
```

---

## File: content/docs/example/enable-http3.md

---
title: Enable HTTP3
---

# Enable HTTP3

HTTP3 is not yet included in the Go standard packages. However, the HTTP3 package is available from the community.

Package: [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go)

Documentation: https://quic-go.net/docs/

## Example

```go
// Refer to quic-go docs to customize configuration
// https://quic-go.net/docs/
http3Transport := &http3.Transport{
    TLSClientConfig: &tls.Config{}, // set a TLS client config, if desired
    QUICConfig: &quic.Config{ // QUIC connection options
        MaxIdleTimeout:  45 * time.Second,
        KeepAlivePeriod: 30 * time.Second,
    },
}
defer http3Transport.Close()

c := resty.New().
    SetTransport(http3Transport)
defer c.Close()

// You're ready to use HTTP3 with Resty
```

---

## File: content/docs/example/get-request.md

---
title: GET Request
weight: 1
---

# GET Request

This page discusses simple GET requests. Resty features can be used across nearly all HTTP methods.

> [!NOTE]
> * Explore the documentation for additional use cases.
> * Examples use request-level methods; however, Resty also includes client-level methods to configure settings for all requests.

## Examples

See [Request Body Types]({{% relref "request-body-types" %}}), [Allow Payload On]({{% relref "allow-payload-on" %}})

```go
// create a Resty client
client := resty.New()
defer client.Close()
```

### Simple

```go
res, err := client.R().
    Get("https://httpbin.org/get")

fmt.Println(err, res)
```

### With Query Params

See [Request Query Params]({{% relref "request-query-params" %}})

```go
res, err := client.R().
    SetQueryParams(map[string]string{
        "page_no": "1",
        "limit":   "20",
        "sort":    "name",
        "order":   "asc",
        "random":  strconv.FormatInt(time.Now().Unix(), 10),
    }).
    SetHeader("Accept", "application/json").
    SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
    Get("/search_result")

fmt.Println(err, res)
```

### With Path Params

See [Request Path Params]({{% relref "request-path-params" %}})

```go
res, err := client.R().
    SetPathParams(map[string]string{
		"userId":       "sample@sample.com",
		"subAccountId": "100002",
	}).
    SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
    Get("/v1/users/{userId}/{subAccountId}/details")

fmt.Println(err, res)
```

### With Payload

See [Allow Payload On]({{% relref "allow-payload-on" %}})

```go
res, err := client.R().
    SetMethodGetAllowPayload(true). // client-level option is available
    SetContentType("application/json").
    SetBody(`{
        "query": {
            "simple_query_string" : {
                "query": "\"fried eggs\" +(eggplant | potato) -frittata",
                "fields": ["title^5", "body"],
                "default_operator": "and"
            }
        }
    }`). // this is string value as request body
    SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
    Get("/_search")

fmt.Println(err, res)
```

---

## File: content/docs/example/how-to-do-dry-run.md

---
title: How to do Dry-Run?
---

# How to do Dry-Run?

The appropriate way to do Dry-Run implementation with Resty is to implement custom transport using the `http.RoundTripper` interface.

With custom transport, the user could perform any use case handling for Dry-Run.

```go
type DryRunTransport struct {
    http.RoundTripper
}

func (dr *DryRunTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    // implement Dry-Run logic here ...

    return resp, err
}

c := resty.New().
    SetTransport(&DryRunTransport{
        // initialize dry-run fields
    })

defer c.Close()

// start using the Resty client with dry-run ...
```

---

## File: content/docs/example/oauth2-client-credentials.md

---
title: OAuth2 Client Credentials
---

# OAuth2 Client Credentials

[](https://pkg.go.dev/golang.org/x/oauth2/clientcredentials)


## Without Modifying

> [!NOTE]
> As per the GoDoc of [clientcredentials#Config.Client](https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config.Client)
> * The returned `Client` and its `Transport` should not be modified.

```go
clientCredCfg := &clientcredentials.Config{
    /* initialize values ... */
}

// create a client
credClient := clientCredCfg.Client(context.Background())

// create a Resty client
c := resty.NewWithClient(credClient)
defer c.Close()

// start using a resty client
```


## Modifying

This scenario applies to any client and transport-related configurations, such as adding Root CA, Client Root CA, Client SSL certificates, transport timeouts, and so on.

> [!NOTE]
> * As per the GoDoc of [clientcredentials#Config.Client](https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config.Client)
>     * The returned `Client` and its `Transport` should not be modified.
> * To use the oauth2 client credentials package and make modifications to it, a minor adjustment is necessary.

```go
clientCredCfg := &clientcredentials.Config{
    /* initialize values ... */
}

// create a Resty client
c := resty.New()
defer c.Close()

// configure required Root CA, Client Root CA, or Client SSL certs
// c.SetRootCertificates("/path/to/root/pemFile.pem")
// c.SetClientRootCertificates("/path/to/client-root/pemFile.pem")
// c.SetCertificateFromFile("/path/to/certs/client.pem", "/path/to/certs/client.key")

// add custom auth request middleware
c.AddRequestMiddleware(func(c *resty.Client, req *resty.Request) error {
    // get the token from client credentials
    token, err := clientCredCfg.Token(req.Context())
    if err != nil {
        return err
    }

    // set it on the request
    req.SetAuthScheme(token.Type()). // if it is "Bearer", you can skip this line
        SetAuthToken(token.AccessToken)

    return nil
})

// start using a resty client
```