{"id":21670509,"url":"https://github.com/engineering87/restschemaretry","last_synced_at":"2025-10-24T02:27:03.682Z","repository":{"id":36533188,"uuid":"189227843","full_name":"engineering87/RESTSchemaRetry","owner":"engineering87","description":"A simple schema Retry for RESTful API","archived":false,"fork":false,"pushed_at":"2024-02-12T15:21:01.000Z","size":154,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2024-04-27T04:35:32.564Z","etag":null,"topics":["dotnet","dotnet-standard","rest-api","restful-api","webapi"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/engineering87.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-05-29T13:09:23.000Z","updated_at":"2024-08-22T11:40:12.123Z","dependencies_parsed_at":"2024-02-12T16:49:41.873Z","dependency_job_id":null,"html_url":"https://github.com/engineering87/RESTSchemaRetry","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineering87%2FRESTSchemaRetry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineering87%2FRESTSchemaRetry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineering87%2FRESTSchemaRetry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineering87%2FRESTSchemaRetry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/engineering87","download_url":"https://codeload.github.com/engineering87/RESTSchemaRetry/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244574666,"owners_count":20474815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet","dotnet-standard","rest-api","restful-api","webapi"],"created_at":"2024-11-25T12:32:43.937Z","updated_at":"2025-10-24T02:27:03.656Z","avatar_url":"https://github.com/engineering87.png","language":"C#","readme":"# RESTSchemaRetry\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Nuget](https://img.shields.io/nuget/v/RESTSchemaRetry?style=plastic)](https://www.nuget.org/packages/RESTSchemaRetry)\n![NuGet Downloads](https://img.shields.io/nuget/dt/RESTSchemaRetry)\n[![issues - RESTSchemaRetry](https://img.shields.io/github/issues/engineering87/RESTSchemaRetry)](https://github.com/engineering87/RESTSchemaRetry/issues)\n[![Build](https://github.com/engineering87/RESTSchemaRetry/actions/workflows/dotnet.yml/badge.svg)](https://github.com/engineering87/RESTSchemaRetry/actions/workflows/dotnet.yml)\n[![stars - RESTSchemaRetry](https://img.shields.io/github/stars/engineering87/RESTSchemaRetry?style=social)](https://github.com/engineering87/RESTSchemaRetry)\n\nRESTSchemaRetry is a .NET library that implements a simple **Schema-Retry** pattern in REST API context to enhance application resilience.\nA Schema-Retry handles transient failures when attempting to connect to a service or network resource by transparently retrying failed operations.\n\n### How it works\nRESTSchemaRetry implements a straightforward retry mechanism with a delay, managing communication timeouts or service errors transparently to the application.\nThe retry mechanism checks the HTTP response code to determine whether the error is transient or not.\n\n### Transient error recovery\nThe library treats the following HTTP statuses as potentially transient:\n\n- **429** Too Many Requests\n- **500** Internal Server Error\n- **502** Bad Gateway\n- **503** Service Unavailable\n- **504** Gateway Timeout\n- **507** Insufficient Storage\n- **408** Request Timeout\n- **505** HTTP Version Not Supported\n- **511** Network Authentication Required\n\n### Supported Backoff Types\n\n- **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.\n  \n- **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)`.\n\n- **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)`.\n  \n- **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.\n  \n- **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)`.\n  \n- **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]`.\n\n- **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).\n\n### Backoff Strategies Comparison\n\n| Backoff Type               | Description                                         | Pros                                            | Cons                                           | Recommended Use Case                               |\n|---------------------------|-----------------------------------------------------|-------------------------------------------------|------------------------------------------------|---------------------------------------------------|\n| **Constant**              | Fixed delay between retries                          | Simple, predictable                             | Can cause retry storms if many clients retry simultaneously | Simple scenarios with low contention               |\n| **Linear**                | Delay increases linearly each retry                  | Gradual increase reduces load                    | May be too slow for high load                    | Moderate retry attempts where steady increase helps |\n| **Exponential**           | Delay doubles every retry                             | Quickly reduces retries, eases server load       | Risk of synchronized retries                     | High contention, backend stress scenarios          |\n| **Exponential with Jitter** | Exponential delay plus random jitter               | Avoids retry synchronization and traffic spikes | Less predictable delay                           | Distributed systems with many clients               |\n| **Fibonacci**             | Delay follows Fibonacci sequence                      | Balanced growth, smoother than exponential      | Slightly more complex                            | When moderate backoff is preferred                   |\n| **Randomized**            | Delay randomly chosen in a range                      | Spreads out retries, avoids bursts                | Delay is unpredictable                           | Systems sensitive to retry bursts                    |\n| **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     |\n\n### How to use it\n\nTo use the RESTSchemaRetry library, just create a **RetryClient** specifying the base URL and the resource.\nThere are multiple constructor to specify the REST API parameters.\n\n```csharp\nvar retryClient = new RetryClient(\"https://example.com/\",\"your-rest-resource\");\n```\n\nThe client supports both default Bearer token authentication and the ability to inject custom headers.\nYou can provide either an authentication token or a dictionary of custom headers as shown below:\n\n```csharp\nvar retryClient = new RetryClient(\n    baseUrl: \"https://example.com/\",\n    resource: \"your-rest-resource\",\n    authToken: \"your-bearer-token\" // optional\n);\n```\nOr with custom headers:\n\n```csharp\nvar customHeaders = new Dictionary\u003cstring, string\u003e\n{\n    { \"Authorization\", \"Bearer your-custom-token\" },\n    { \"X-Custom-Header\", \"value\" }\n};\n\nvar retryClient = new RetryClient(\n    baseUrl: \"https://example.com/\",\n    resource: \"your-rest-resource\",\n    defaultHeaders: customHeaders\n);\n```\n\nAt this point the REST API requests can be performed.\nFor example, below how to execute a POST request:\n\n```csharp\nvar response = retryClient.Post\u003cTRequest, TResponse\u003e(objectToPost);\n```\nAlternatively, you can register the library via dependency injection as follows:\n\n```csharp\nbuilder.Services.AddRetryClient(\"https://your-base-url.com\", \"your-rest-resource\");\n```\n\nRESTSchemaRetry uses the **RestSharp** library to execute the web requests.\n\n### NuGet Package\n\nThe library is available on NuGet package manager.\nhttps://www.nuget.org/packages/RESTSchemaRetry/\n\n### RestSharp Reference\nRESTSchemaRetry uses the **RestSharp** library, which is distributed under Apache 2.0 license.\n* [Official Project](https://github.com/restsharp/RestSharp)\n* [License](https://github.com/restsharp/RestSharp/blob/dev/LICENSE.txt)\n\n## Contributing\nThank you for considering to help out with the source code!\nIf 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.\n\n * [Setting up Git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git)\n * [Fork the repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)\n * [Open an issue](https://github.com/engineering87/RESTSchemaRetry/issues) if you encounter a bug or have a suggestion for improvements/features\n\n### License\nRESTSchemaRetry source code is available under MIT License, see license in the source.\n\n### Contact\nPlease contact at francesco.delre[at]protonmail.com for any details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineering87%2Frestschemaretry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fengineering87%2Frestschemaretry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineering87%2Frestschemaretry/lists"}