Skip to content

Commit

Permalink
add docs for retry and circuit breaker
Browse files Browse the repository at this point in the history
- update docs for curl cmd and upgrading v3
- update license file
  • Loading branch information
jeevatkm committed Jan 1, 2025
1 parent 2682428 commit 651afe9
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 24 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2024-Present Jeevanandam M ([email protected])

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
42 changes: 42 additions & 0 deletions content/docs/circuit-breaker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

# Circuit Breaker

A circuit breaker is used to improve system stability and resiliency. It is different from the retry mechanism.

{{% hint info %}}
**Hint:** Combining the Circuit Breaker with [Retry Mechanism]({{% relref "retry-mechanism" %}}) typically provides a comprehensive approach to handling failures.
{{% /hint %}}

## Default Values

* Timeout is `10s`
* Failure threshold is `3`
* Success threshold is `1`
* Circuir break policy
* Status Code `500` and above


## Example

```go
// create circuit breaker with required values, override as required
cb := resty.NewCircuitBreaker().
SetTimeout(15 * time.Second).
SetFailThreshold(10).
SetSuccessThreshold(5)

// create Resty client
client := resty.New().
SetCircuitBreaker(cb)
defer client.Close()

// start using the client ...
```


## Methods

* [CircuitBreaker.SetTimeout]({{% param Resty.V3.GoDocLinkPrefix %}}CircuitBreaker.SetTimeout)
* [CircuitBreaker.SetFailThreshold]({{% param Resty.V3.GoDocLinkPrefix %}}CircuitBreaker.SetFailThreshold)
* [CircuitBreaker.SetSuccessThreshold]({{% param Resty.V3.GoDocLinkPrefix %}}CircuitBreaker.SetSuccessThreshold)
* [CircuitBreaker.SetPolicies]({{% param Resty.V3.GoDocLinkPrefix %}}CircuitBreaker.SetPolicies)
45 changes: 26 additions & 19 deletions content/docs/curl-command.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,53 @@
---
title: "CURL Command Generation"
bookHidden: true
---

# CURL Command Generation
# Curl Command

Resty provides a way to generate the CURL command in debug mode.
Resty provides an option to generate the curl command for the request.

By default, Resty does not log the curl command in the debug log since it has the potential to leak sensitive data unless explicitly enabled via [Client.SetDebugLogCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetDebugLogCurlCmd).

{{% hint info %}}
**NOTE:** Client-level settings can be overridden at the request level.
{{% /hint %}}

{{% hint warning %}}
**NOTE:**

- Potential to leak sensitive data from [Request]() and [Response]() in the debug log.
- Beware of memory usage since the request body is reread.
- Potential to leak sensitive data from [Request]({{% param Resty.V3.GoDocLinkPrefix %}}Request) and [Response]({{% param Resty.V3.GoDocLinkPrefix %}}Response) in the debug log when the debug log option is enabled.
- Additional memory usage since the request body was reread.
- curl body is not generated for `io.Reader` and multipart request flow.
{{% /hint %}}

## Methods
* [Client.EnableGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Client.EnableGenerateCurlOnDebug)
* [Client.DisableGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Client.DisableGenerateCurlOnDebug)
* [Client.SetGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetGenerateCurlOnDebug)
* [Request.EnableGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Request.EnableGenerateCurlOnDebug)
* [Request.DisableGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DisableGenerateCurlOnDebug)
* [Request.SetGenerateCurlOnDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetGenerateCurlOnDebug)
## Example

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

res, err := c.R().
EnableDebug().
EnableGenerateCurlOnDebug().
SetGenerateCurlCmd(true).
SetBody(map[string]string{
"name": "Alex",
}).
Post("https://httpbin.org/post")

curlCmdStr := res.Request.GenerateCurlCommand()
curlCmdStr := res.Request.CurlCommand()
fmt.Println(err, curlCmdStr)

// Result:
// curl -X POST -H 'Content-Type: application/json' -H 'User-Agent: go-resty/3.0.0 (https://resty.dev)' -d '{"name":"Alex"}' https://httpbin.org/post
```

## Methods

### Client

* [Client.EnableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.EnableGenerateCurlCmd)
* [Client.DisableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.DisableGenerateCurlCmd)
* [Client.SetGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetGenerateCurlCmd)
* [Client.SetDebugLogCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetDebugLogCurlCmd)

### Request

* [Request.EnableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.EnableGenerateCurlCmd)
* [Request.DisableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DisableGenerateCurlCmd)
* [Request.SetGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetGenerateCurlCmd)
* [Request.SetDebugLogCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetDebugLogCurlCmd)
118 changes: 118 additions & 0 deletions content/docs/retry-mechanism.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

# Retry Mechanism

The retry mechanism plays a crucial role in modern system integration by enabling effective handling of failures.

Resty provides exponential backoff with a jitter strategy out of the box; a custom retry strategy could be employed to override this default.

{{% hint info %}}
**Hint:** Combining the Retry strategy with [Circuit Breaker]({{% relref "circuit-breaker" %}}) typically provides a comprehensive approach to handling failures.
{{% /hint %}}


## Default Values

* Retry count is `0`
* Total retry attempts = `first attempt + retry count`
* Retry minimum wait time is `100ms`
* Retry maximum wait time is `2000ms`
* Retry strategy is exponential backoff with a jitter


## Default Behavior

* Respects header `Retry-After` if present
* Resets reader on retry request if the `io.ReadSeeker` interface is supported.
* Retries only on Idempotent HTTP Verb - GET, HEAD, PUT, DELETE, OPTIONS, and TRACE ([RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110.html#name-method-registration), [RFC 5789](https://datatracker.ietf.org/doc/html/rfc5789.html))
* Use [Client.SetAllowNonIdempotentRetry]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetAllowNonIdempotentRetry) or [Request.SetAllowNonIdempotentRetry]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetAllowNonIdempotentRetry). If additional control is necessary, utilize the custom retry condition.
* Applies [default retry conditions]({{% relref "#default-conditions" %}})
* It can be disabled via [Client.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryDefaultConditions) or [Request.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryDefaultConditions)


## Default Conditions

* Condition gets applied in the following order
* No Retry
* TLS certificate verification error
* Too many redirects error
* Scheme error
* Invalid header error
* Response is nil
* Retry
* Status Code is 429 Too Many Requests
* Status Code is 500 or above (but not Status Code 501 Not Implemented)
* Status Code is 0


## Examples

```go
// Retry configuration can be set at the client or request level
client.
SetRetryCount(3).
SetRetryWaitTime(2 * time.Second).
SetRetryMaxWaitTime(5 * time.Second)
```

### Constant Delay

Use a custom retry strategy approach to perform constant/fixed delay.

```go
// Retry configuration can be set at the client or request level
client.
SetRetryStrategy(func(_ *resty.Response, _ error) (time.Duration, error) {
return 3 * time.Second, nil
})
```

### Retry Hook

Utilize the retry hook(s) to perform logic between retries.

```go
// Retry configuration can be set at the client or request level
client.
AddRetryHook(func(res *resty.Response, err error) {
// perform logic here
})
```

### Retry Conditions

```go
// Retry configuration can be set at the client or request level
// NOTE: first default retry conditions get applied
// before user-defined retry conditions
client.
AddRetryCondition(func(res *resty.Response, err error) bool {
// perform logic here

// return true if retry is required otherwise, return false
return true
})
```


## Methods

### Client

* [Client.SetRetryCount]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryCount)
* [Client.SetRetryWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryWaitTime)
* [Client.SetRetryMaxWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryMaxWaitTime)
* [Client.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryStrategy)
* [Client.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryDefaultConditions)
* [Client.AddRetryHook]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AddRetryHook)
* [Client.AddRetryCondition]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AddRetryCondition)


### Request

* [Request.SetRetryCount]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryCount)
* [Request.SetRetryWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryWaitTime)
* [Request.SetRetryMaxWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryMaxWaitTime)
* [Request.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryStrategy)
* [Request.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryDefaultConditions)
* [Request.AddRetryHook]({{% param Resty.V3.GoDocLinkPrefix %}}Request.AddRetryHook)
* [Request.AddRetryCondition]({{% param Resty.V3.GoDocLinkPrefix %}}Request.AddRetryCondition)
46 changes: 42 additions & 4 deletions content/docs/upgrading-to-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ I made necessary breaking changes to improve Resty and open up future growth pos

* Set Content length is not applicable for `io.Reader` flow.
* By default, payload is not supported in HTTP verb DELETE. Use [Client.AllowMethodDeletePayload]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AllowMethodDeletePayload) or [Request.AllowMethodDeletePayload]({{% param Resty.V3.GoDocLinkPrefix %}}Request.AllowMethodDeletePayload).
* Retry Mechanism
* Respects header `Retry-After` if present
* Resets reader on retry request if the `io.ReadSeeker` interface is supported.
* Retries only on Idempotent HTTP Verb - GET, HEAD, PUT, DELETE, OPTIONS, and TRACE ([RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110.html#name-method-registration), [RFC 5789](https://datatracker.ietf.org/doc/html/rfc5789.html)),
* Use [Client.SetAllowNonIdempotentRetry]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetAllowNonIdempotentRetry) or [Request.SetAllowNonIdempotentRetry]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetAllowNonIdempotentRetry). If additional control is necessary, utilize the custom retry condition.
* Applies [default retry conditions]({{% relref "retry-mechanism#default-conditions" %}})
* It can be disabled via [Client.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryDefaultConditions) or [Request.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryDefaultConditions)
*

#### Client

Expand All @@ -40,6 +48,8 @@ I made necessary breaking changes to improve Resty and open up future growth pos
* [Client.ResponseBodyLimit]({{% param Resty.V3.GoDocLinkPrefix %}}Client.ResponseBodyLimit) - datatype changed from `int` to `int64`
* `Client.SetAllowGetMethodPayload` => [Client.SetAllowMethodGetPayload]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetAllowMethodGetPayload)
* `Client.Clone()` - use [Client.Clone(ctx context.Context)]({{% param Resty.V3.GoDocLinkPrefix %}}Client.Clone) instead.
* `Client.EnableGenerateCurlOnDebug` => [Client.EnableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.EnableGenerateCurlCmd)
* `Client.DisableGenerateCurlOnDebug` => [Client.DisableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.DisableGenerateCurlCmd)

#### Request

Expand All @@ -48,19 +58,27 @@ I made necessary breaking changes to improve Resty and open up future growth pos
* `Request.NotParseResponse` => [Request.DoNotParseResponse]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DoNotParseResponse)
* `Request.ExpectContentType` => [Request.SetExpectResponseContentType]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetExpectResponseContentType)
* `Request.ForceContentType` => [Request.SetForceResponseContentType]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetForceResponseContentType)
* `Request.SetOutput` => [Request.SetOutputFileName]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetOutputFileName)
* `Request.EnableGenerateCurlOnDebug` => [Request.EnableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.EnableGenerateCurlCmd)
* `Request.DisableGenerateCurlOnDebug` => [Request.DisableGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DisableGenerateCurlCmd)
* `Request.GenerateCurlCommand` => [Request.CurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.CurlCmd)


### Removed

#### Client

* `Client.SetHostURL` - use [Client.SetBaseURL]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetBaseURL) instead.
* `Client.{SetJSONMarshaler, SetJSONUnmarshaler, SetXMLMarshaler, SetXMLUnmarshaler}` - use [Client.AddContentTypeEncoder]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AddContentTypeEncoder) and [Client.AddContentTypeDecoder]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AddContentTypeDecoder) instead.
* `Client.RawPathParams` - use `Client.PathParams()` instead
* `Client.RawPathParams` - use `Client.PathParams()` instead.
* `Client.UserInfo`
* `Client.SetRetryResetReaders` - it happens automatically.
* `Client.SetRetryAfter` - use [Client.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryStrategy) or [Request.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryStrategy) instead.

#### Request

* `Request.RawPathParams` - use [Request.PathParams]({{% param Resty.V3.GoDocLinkPrefix %}}Request.PathParams) instead
*

#### Response

Expand All @@ -79,6 +97,10 @@ I made necessary breaking changes to improve Resty and open up future growth pos

## New Features and Enhancements

* Override all transport settings and timeout values used by Resty using [NewWithTransportSettings]({{% param Resty.V3.GoDocLinkPrefix %}}NewWithTransportSettings)
* [Circuit Breaker]({{% relref "circuit-breaker" %}})
* Set retry settings on Request instance refer to [Retry Mechanism]({{% relref "retry-mechanism" %}})

### New ways to create Client

* [NewWithTransportSettings]({{% param Resty.V3.GoDocLinkPrefix %}}NewWithTransportSettings)
Expand All @@ -104,6 +126,12 @@ I made necessary breaking changes to improve Resty and open up future growth pos
* [Client.IsDisableWarn]({{% param Resty.V3.GoDocLinkPrefix %}}Client.IsDisableWarn)
* [Client.AllowMethodDeletePayload]({{% param Resty.V3.GoDocLinkPrefix %}}Client.AllowMethodDeletePayload)
* [Client.SetAllowMethodDeletePayload]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetAllowMethodDeletePayload)
* [Client.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryStrategy)
* [Client.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetRetryDefaultConditions)
* [Client.IsSaveResponse]({{% param Resty.V3.GoDocLinkPrefix %}}Client.IsSaveResponse)
* [Client.SetSaveResponse]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetSaveResponse)
* [Client.SetGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetGenerateCurlCmd)
* [Client.SetDebugLogCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Client.SetDebugLogCurlCmd)

### Request

Expand All @@ -113,7 +141,7 @@ I made necessary breaking changes to improve Resty and open up future growth pos
* [Request.DebugBodyLimit]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DebugBodyLimit)
* [Request.EnableDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Request.EnableDebug)
* [Request.DisableDebug]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DisableDebug)
* [Request.IsTrace]({{% param Resty.V3.GoDocLinkPrefix %}}Request.IsTrace)
* [Request.IsTrace]({{% param Resty.V3.GoDocLinkPrefix %}}Request)
* [Request.SetTrace]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetTrace)
* [Request.DisableTrace]({{% param Resty.V3.GoDocLinkPrefix %}}Request.DisableTrace)
* [Request.Patch]({{% param Resty.V3.GoDocLinkPrefix %}}Request.Patch)
Expand All @@ -122,11 +150,21 @@ I made necessary breaking changes to improve Resty and open up future growth pos
* [Request.SetURL](R{{% param Resty.V3.GoDocLinkPrefix %}}equest.SetURL)
* [Request.SetAllowMethodGetPayload]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetAllowMethodGetPayload)
* [Request.SetAllowMethodDeletePayload]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetAllowMethodDeletePayload)
* [Request.SetRetryCount]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryCount)
* [Request.SetRetryWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryWaitTime)
* [Request.SetRetryMaxWaitTime]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryMaxWaitTime)
* [Request.SetRetryStrategy]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryStrategy)
* [Request.SetRetryDefaultConditions]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetRetryDefaultConditions)
* [Request.IsSaveResponse]({{% param Resty.V3.GoDocLinkPrefix %}}Request)
* [Request.SetSaveResponse]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetSaveResponse)
* [Request.SetGenerateCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetGenerateCurlCmd)
* [Request.SetDebugLogCurlCmd]({{% param Resty.V3.GoDocLinkPrefix %}}Request.SetDebugLogCurlCmd)


### Response

* [Response.Body]({{% param Resty.V3.GoDocLinkPrefix %}}Response)
* [Response.SetBodyBytes]({{% param Resty.V3.GoDocLinkPrefix %}}Response.SetBodyBytes)
* [Response.Bytes]({{% param Resty.V3.GoDocLinkPrefix %}}Response.Bytes)
* [Response.IsRead]({{% param Resty.V3.GoDocLinkPrefix %}}Response)
* [Response.Err]({{% param Resty.V3.GoDocLinkPrefix %}}Response)
* [Response.Err]({{% param Resty.V3.GoDocLinkPrefix %}}Response)
* [Response.RedirectHistory]({{% param Resty.V3.GoDocLinkPrefix %}}Response.RedirectHistory)

0 comments on commit 651afe9

Please sign in to comment.