{"id":51349043,"url":"https://github.com/slashdevops/httpretrier","last_synced_at":"2026-07-02T14:40:13.522Z","repository":{"id":290029523,"uuid":"973115395","full_name":"slashdevops/httpretrier","owner":"slashdevops","description":"Golang http retrier library","archived":false,"fork":false,"pushed_at":"2026-06-24T20:02:41.000Z","size":62,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-24T21:19:36.604Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slashdevops.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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-26T09:41:23.000Z","updated_at":"2026-06-24T20:02:49.000Z","dependencies_parsed_at":"2025-04-26T12:36:00.264Z","dependency_job_id":"86014eb5-1dcc-445b-a303-f54d33ce16ec","html_url":"https://github.com/slashdevops/httpretrier","commit_stats":null,"previous_names":["p2p-b2b/httpretrier","slashdevops/httpretrier"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/slashdevops/httpretrier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slashdevops%2Fhttpretrier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slashdevops%2Fhttpretrier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slashdevops%2Fhttpretrier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slashdevops%2Fhttpretrier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slashdevops","download_url":"https://codeload.github.com/slashdevops/httpretrier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slashdevops%2Fhttpretrier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35051883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-07-02T14:40:11.477Z","updated_at":"2026-07-02T14:40:13.413Z","avatar_url":"https://github.com/slashdevops.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# httpretrier\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/slashdevops/httpretrier.svg)](https://pkg.go.dev/github.com/slashdevops/httpretrier)\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/slashdevops/httpretrier?style=plastic)\n\n`httpretrier` is a Go library that provides a **transparent** drop-in replacement for `http.Client` with automatic retry logic. It preserves all existing request headers (including authentication) while handling transient server errors (5xx) or network issues by retrying requests based on configurable strategies.\n\n## Features\n\n* **Transparent by Default:** Works as a zero-configuration drop-in replacement for `http.Client`, automatically preserving existing authentication tokens, custom headers, and all request properties without any code changes.\n* **Automatic Retries:** Automatically retries requests that fail due to server errors (5xx) or transport-level errors.\n* **Configurable Retry Strategies:**\n  * `FixedDelay`: Retries after a constant delay.\n  * `ExponentialBackoff`: Retries with exponentially increasing delays.\n  * `JitterBackoff`: Retries with exponential backoff plus random jitter to prevent thundering herd issues.\n* **Flexible Configuration:** Use the `ClientBuilder` for fine-grained control over:\n  * Maximum number of retries.\n  * Base and maximum delay for backoff strategies.\n  * Standard `http.Transport` settings (timeouts, keep-alives, connection pooling).\n  * Overall request timeout (`http.Client.Timeout`).\n* **Easy Integration:** Designed as a complete drop-in replacement for `http.Client` - just change your client creation line and everything else works transparently.\n\n## Installation\n\n```bash\ngo get github.com/slashdevops/httpretrier@latest\n```\n\n## Update\n\n```bash\ngo get -u github.com/slashdevops/httpretrier@latest\n```\n\n## Usage\n\n### Basic Transparent Usage (Recommended)\n\nThe easiest way to add retry functionality is to replace your `http.Client` with `httpretrier.NewClient()`. It works transparently with all existing headers and authentication tokens.\n\n```go\n// Before: client := \u0026http.Client{}\nclient := httpretrier.NewClient(3, httpretrier.ExponentialBackoff(500*time.Millisecond, 10*time.Second), nil)\n\n// All your existing code works unchanged - auth tokens, custom headers, everything is preserved\nreq, _ := http.NewRequest(\"GET\", \"https://api.example.com/data\", nil)\nreq.Header.Set(\"Authorization\", \"Bearer your-existing-token\")\nreq.Header.Set(\"X-Custom-Header\", \"your-value\")\n\nresp, err := client.Do(req)\n// Automatically retries on 5xx errors while preserving all headers\n```\n\n### Basic Usage with Specific Configuration\n\nYou can create a client with specific retry strategy and number of retries using `httpretrier.NewClient`.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"io\"\n  \"net/http\"\n  \"net/http/httptest\"\n  \"sync/atomic\"\n  \"time\"\n\n  \"github.com/slashdevops/httpretrier\"\n)\n\nfunc main() {\n  var requestCount int32\n  // Example server that fails the first few requests\n  server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    count := atomic.AddInt32(\u0026requestCount, 1)\n    if count \u003c= 2 { // Fail first 2 times\n      fmt.Printf(\"Server: Request %d -\u003e 500 Internal Server Error\\n\", count)\n      w.WriteHeader(http.StatusInternalServerError)\n    } else {\n      fmt.Printf(\"Server: Request %d -\u003e 200 OK\\n\", count)\n      w.WriteHeader(http.StatusOK)\n      _, _ = w.Write([]byte(\"Success!\"))\n    }\n  }))\n  defer server.Close()\n\n  // Create a client with exponential backoff (3 retries, 10ms base, 100ms max delay)\n  retryClient := httpretrier.NewClient(\n    3, // Max Retries\n    httpretrier.ExponentialBackoff(10*time.Millisecond, 100*time.Millisecond),\n    nil, // Use http.DefaultTransport\n  )\n\n  fmt.Println(\"Client: Making request...\")\n  resp, err := retryClient.Get(server.URL)\n  if err != nil {\n    fmt.Printf(\"Client: Request failed after retries: %v\\n\", err)\n    return\n  }\n  defer resp.Body.Close()\n\n  body, _ := io.ReadAll(resp.Body)\n  fmt.Printf(\"Client: Received response: Status=%s, Body='%s'\\n\", resp.Status, string(body))\n}\n\n// Example Output:\n// Client: Making request...\n// Server: Request 1 -\u003e 500 Internal Server Error\n// Server: Request 2 -\u003e 500 Internal Server Error\n// Server: Request 3 -\u003e 200 OK\n// Client: Received response: Status=200 OK, Body='Success!'\n```\n\n### Using Custom Transport\n\nYou can provide your own `http.Transport` with specific settings for connection pooling, timeouts, TLS configuration, etc.:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"net/http\"\n  \"time\"\n\n  \"github.com/slashdevops/httpretrier\"\n)\n\nfunc main() {\n  // Create a custom transport with specific settings\n  customTransport := \u0026http.Transport{\n    MaxIdleConns:        50,                // Custom connection pool size\n    IdleConnTimeout:     30 * time.Second, // Custom idle timeout\n    DisableKeepAlives:   false,            // Enable keep-alives\n    MaxIdleConnsPerHost: 10,               // Custom per-host connection limit\n    TLSHandshakeTimeout: 5 * time.Second,  // Custom TLS timeout\n  }\n\n  // Create retry client with your custom transport\n  client := httpretrier.NewClient(\n    3, // Max retries\n    httpretrier.ExponentialBackoff(100*time.Millisecond, 1*time.Second),\n    customTransport, // Use your custom transport as the base\n  )\n\n  // Use the client normally - all your transport settings are preserved\n  resp, err := client.Get(\"https://api.example.com/data\")\n  if err != nil {\n    fmt.Printf(\"Request failed: %v\\n\", err)\n    return\n  }\n  defer resp.Body.Close()\n\n  // Your custom transport settings (connection pooling, timeouts) are used\n  // while still getting automatic retry functionality\n  fmt.Printf(\"Success with custom transport! Status: %d\\n\", resp.StatusCode)\n}\n```\n\n### Advanced Configuration with ClientBuilder\n\nFor more control over the client and transport settings, use the `ClientBuilder`.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"io\"\n  \"net/http\"\n  \"net/http/httptest\"\n  \"time\"\n\n  \"github.com/slashdevops/httpretrier\"\n)\n\nfunc main() {\n  // Example server\n  server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    w.WriteHeader(http.StatusOK)\n    _, _ = w.Write([]byte(\"Builder success!\"))\n  }))\n  defer server.Close()\n\n  // Use the builder for detailed configuration\n  builder := httpretrier.NewClientBuilder()\n\n  httpClient := builder.\n    WithTimeout(15 * time.Second).          // Overall request timeout\n    WithMaxRetries(5).                      // Max 5 retries\n    WithRetryStrategy(httpretrier.JitterBackoffStrategy). // Use Jitter strategy\n    WithRetryBaseDelay(100 * time.Millisecond). // 100ms base delay\n    WithRetryMaxDelay(2 * time.Second).       // 2s max delay\n    WithMaxIdleConns(50).                   // Transport: Max 50 idle connections\n    WithIdleConnTimeout(30 * time.Second).    // Transport: 30s idle timeout\n    Build()                                 // Build the http.Client\n\n  fmt.Println(\"Client (Builder): Making request...\")\n  resp, err := httpClient.Get(server.URL)\n  if err != nil {\n    fmt.Printf(\"Client (Builder): Request failed: %v\\n\", err)\n    return\n  }\n  defer resp.Body.Close()\n\n  body, _ := io.ReadAll(resp.Body)\n  fmt.Printf(\"Client (Builder): Received response: Status=%s, Body='%s'\\n\", resp.Status, string(body))\n}\n\n// Example Output:\n// Client (Builder): Making request...\n// Client (Builder): Received response: Status=200 OK, Body='Builder success!'\n```\n\n## Configuration Options (ClientBuilder)\n\nThe `ClientBuilder` allows configuration of:\n\n* **Retry Logic:**\n  * `WithMaxRetries(int)`: Maximum number of retry attempts.\n  * `WithRetryStrategy(httpretrier.Strategy)`: Set the strategy (`FixedDelayStrategy`, `ExponentialBackoffStrategy`, `JitterBackoffStrategy`).\n  * `WithRetryBaseDelay(time.Duration)`: Base delay for backoff/jitter, or the fixed delay duration.\n  * `WithRetryMaxDelay(time.Duration)`: Maximum delay cap for backoff/jitter strategies.\n* **HTTP Client:**\n  * `WithTimeout(time.Duration)`: Sets the `Timeout` field on the resulting `http.Client`.\n* **HTTP Transport:** (Controls the underlying `http.Transport`)\n  * `WithMaxIdleConns(int)`\n  * `WithIdleConnTimeout(time.Duration)`\n  * `WithTLSHandshakeTimeout(time.Duration)`\n  * `WithExpectContinueTimeout(time.Duration)`\n  * `WithDisableKeepAlives(bool)`\n  * `WithMaxIdleConnsPerHost(int)`\n\nSee the Go documentation for default values and validation ranges for these parameters.\n\n## License\n\nThis library is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslashdevops%2Fhttpretrier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslashdevops%2Fhttpretrier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslashdevops%2Fhttpretrier/lists"}