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
Versioning
Resty releases versions according to Semantic Versioning
- Resty v3 provides Go Vanity URL
resty.dev/v3. - Resty v2 migrated away from
gopkg.inservice,github.com/go-resty/resty/v2. - Resty fully adapted to
go modcapabilities sincev1.10.0release. - Resty v1 series was using
gopkg.into provide versioning.gopkg.in/resty.vXpoints to appropriate tagged versions;Xdenotes 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. It means a lot to me.
Creator
Jeevanandam M. ([email protected])
Contributors
Have a look on Contributors page.
License Info
Resty released under MIT LICENSE.
Resty Documentation and website released under Apache-2.0 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.
hugo server --minifyGo to http://localhost:1313/ to see the documentation website.
Contributors
Have a look on Contributors page.
License Info
Resty Documentation and website released under Apache-2.0 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.
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]
Usingsync.Poolcan reuse the reader and reduce allocation if the package supportsReset.
Example 1
Package: github.com/andybalholm/brotli
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
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]
Usingsync.Poolcan reuse the reader and reduce allocation if the package supportsReset.
Example
Package: github.com/klauspost/compress/zstd
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" %}})
// create a Resty client
client := resty.New()
defer client.Close()Simple
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" %}})
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
Documentation: https://quic-go.net/docs/
Example
// 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 RestyFile: 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" %}})
// create a Resty client
client := resty.New()
defer client.Close()Simple
res, err := client.R().
Get("https://httpbin.org/get")
fmt.Println(err, res)With Query Params
See [Request Query Params]({{% relref "request-query-params" %}})
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" %}})
res, err := client.R().
SetPathParams(map[string]string{
"userId": "[email protected]",
"subAccountId": "100002",
}).
SetAuthToken("bc594900518b4f7eac75bd37f019e08fbc594900518b4f7eac75bd37f019e08f").
Get("/v1/users/{userId}/{subAccountId}/details")
fmt.Println(err, res)With Payload
See [Allow Payload On]({{% relref "allow-payload-on" %}})
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.
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
Without Modifying
[!NOTE]
As per the GoDoc of clientcredentials#Config.Client
- The returned
Clientand itsTransportshould not be modified.
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 clientModifying
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
- The returned
Clientand itsTransportshould not be modified.- To use the oauth2 client credentials package and make modifications to it, a minor adjustment is necessary.
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