https://github.com/engineering87/restschemaretry
A simple schema Retry for RESTful API
https://github.com/engineering87/restschemaretry
dotnet dotnet-standard rest-api restful-api webapi
Last synced: 6 months ago
JSON representation
A simple schema Retry for RESTful API
- Host: GitHub
- URL: https://github.com/engineering87/restschemaretry
- Owner: engineering87
- License: mit
- Created: 2019-05-29T13:09:23.000Z (almost 7 years ago)
- Default Branch: develop
- Last Pushed: 2024-02-12T15:21:01.000Z (about 2 years ago)
- Last Synced: 2024-04-27T04:35:32.564Z (almost 2 years ago)
- Topics: dotnet, dotnet-standard, rest-api, restful-api, webapi
- Language: C#
- Size: 150 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RESTSchemaRetry
[](https://opensource.org/licenses/MIT)
[](https://www.nuget.org/packages/RESTSchemaRetry)

[](https://github.com/engineering87/RESTSchemaRetry/issues)
[](https://github.com/engineering87/RESTSchemaRetry/actions/workflows/dotnet.yml)
[](https://github.com/engineering87/RESTSchemaRetry)
RESTSchemaRetry is a .NET library that implements a simple **Schema-Retry** pattern in REST API context to enhance application resilience.
A Schema-Retry handles transient failures when attempting to connect to a service or network resource by transparently retrying failed operations.
### How it works
RESTSchemaRetry implements a straightforward retry mechanism with a delay, managing communication timeouts or service errors transparently to the application.
The retry mechanism checks the HTTP response code to determine whether the error is transient or not.
### Transient error recovery
The library treats the following HTTP statuses as potentially transient:
- **429** Too Many Requests
- **500** Internal Server Error
- **502** Bad Gateway
- **503** Service Unavailable
- **504** Gateway Timeout
- **507** Insufficient Storage
- **408** Request Timeout
- **505** HTTP Version Not Supported
- **511** Network Authentication Required
### Supported Backoff Types
- **Constant Backoff**: The delay between retries is constant and does not change. This is a simple approach where each retry attempt waits for a fixed amount of time, defined by a `RetryDelay` parameter.
- **Linear Backoff**: The delay between retries increases linearly. Each retry attempt waits longer than the previous one by a fixed increment. The delay is calculated as `RetryDelay * (retry + 1)`.
- **Exponential Backoff**: The delay between retries grows exponentially. The delay is calculated using a power of 2, multiplied by the base RetryDelay. This approach is useful to quickly back off from a failing operation, reducing server load. Formula: `RetryDelay * (2 ^ retry)`.
- **Exponential Backoff with Jitter**: Similar to exponential backoff, but with added randomness ("jitter") to the delay to avoid synchronized retries from multiple clients, which can cause spikes in traffic. The delay is calculated as `RetryDelay * (2 ^ retry) * random_factor`, where `random_factor` is a random value between 0 and 1.
- **Fibonacci Backoff**: The delay between retries follows the Fibonacci sequence. This provides a middle ground between linear and exponential backoff, growing less aggressively than exponential. The delay is calculated as `RetryDelay * Fibonacci(retry)`.
- **Randomized Backoff**: The delay is randomly chosen between a minimum and a maximum range, usually defined as a multiple of RetryDelay. This helps to distribute retries more evenly over time, avoiding bursts of traffic. The delay is calculated randomly within a range, e.g., `[RetryDelay, RetryDelay * 2]`.
- **Exponential Full Jitter Backoff**: This strategy provides exponential backoff with full jitter. It’s especially effective for reducing collision and spreading retries over `time.delay = random(0, RetryDelay * 2^retry)` (capped to a max delay).
### Backoff Strategies Comparison
| Backoff Type | Description | Pros | Cons | Recommended Use Case |
|---------------------------|-----------------------------------------------------|-------------------------------------------------|------------------------------------------------|---------------------------------------------------|
| **Constant** | Fixed delay between retries | Simple, predictable | Can cause retry storms if many clients retry simultaneously | Simple scenarios with low contention |
| **Linear** | Delay increases linearly each retry | Gradual increase reduces load | May be too slow for high load | Moderate retry attempts where steady increase helps |
| **Exponential** | Delay doubles every retry | Quickly reduces retries, eases server load | Risk of synchronized retries | High contention, backend stress scenarios |
| **Exponential with Jitter** | Exponential delay plus random jitter | Avoids retry synchronization and traffic spikes | Less predictable delay | Distributed systems with many clients |
| **Fibonacci** | Delay follows Fibonacci sequence | Balanced growth, smoother than exponential | Slightly more complex | When moderate backoff is preferred |
| **Randomized** | Delay randomly chosen in a range | Spreads out retries, avoids bursts | Delay is unpredictable | Systems sensitive to retry bursts |
| **Exponential Full Jitter**| Exponential delay with full jitter randomized | Minimizes collision, best spread of retries | More complex, highly variable delay | Stateless retries, high concurrency environments |
### How to use it
To use the RESTSchemaRetry library, just create a **RetryClient** specifying the base URL and the resource.
There are multiple constructor to specify the REST API parameters.
```csharp
var retryClient = new RetryClient("https://example.com/","your-rest-resource");
```
The client supports both default Bearer token authentication and the ability to inject custom headers.
You can provide either an authentication token or a dictionary of custom headers as shown below:
```csharp
var retryClient = new RetryClient(
baseUrl: "https://example.com/",
resource: "your-rest-resource",
authToken: "your-bearer-token" // optional
);
```
Or with custom headers:
```csharp
var customHeaders = new Dictionary
{
{ "Authorization", "Bearer your-custom-token" },
{ "X-Custom-Header", "value" }
};
var retryClient = new RetryClient(
baseUrl: "https://example.com/",
resource: "your-rest-resource",
defaultHeaders: customHeaders
);
```
At this point the REST API requests can be performed.
For example, below how to execute a POST request:
```csharp
var response = retryClient.Post(objectToPost);
```
Alternatively, you can register the library via dependency injection as follows:
```csharp
builder.Services.AddRetryClient("https://your-base-url.com", "your-rest-resource");
```
RESTSchemaRetry uses the **RestSharp** library to execute the web requests.
### NuGet Package
The library is available on NuGet package manager.
https://www.nuget.org/packages/RESTSchemaRetry/
### RestSharp Reference
RESTSchemaRetry uses the **RestSharp** library, which is distributed under Apache 2.0 license.
* [Official Project](https://github.com/restsharp/RestSharp)
* [License](https://github.com/restsharp/RestSharp/blob/dev/LICENSE.txt)
## Contributing
Thank you for considering to help out with the source code!
If you'd like to contribute, please fork, fix, commit and send a pull request for the maintainers to review and merge into the main code base.
* [Setting up Git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git)
* [Fork the repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)
* [Open an issue](https://github.com/engineering87/RESTSchemaRetry/issues) if you encounter a bug or have a suggestion for improvements/features
### License
RESTSchemaRetry source code is available under MIT License, see license in the source.
### Contact
Please contact at francesco.delre[at]protonmail.com for any details.