{"id":19386838,"url":"https://github.com/shuvava/go-enrichable-client","last_synced_at":"2026-06-20T14:31:45.113Z","repository":{"id":57619406,"uuid":"356610430","full_name":"shuvava/go-enrichable-client","owner":"shuvava","description":"Retryable http client","archived":false,"fork":false,"pushed_at":"2023-04-26T22:03:51.000Z","size":94,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-03T19:28:06.904Z","etag":null,"topics":["cloud","golang","http","rest"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shuvava.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}},"created_at":"2021-04-10T14:44:49.000Z","updated_at":"2022-01-22T15:41:20.000Z","dependencies_parsed_at":"2024-06-20T13:27:26.185Z","dependency_job_id":"9923021b-269c-4943-a8f0-42ea19c53709","html_url":"https://github.com/shuvava/go-enrichable-client","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/shuvava/go-enrichable-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuvava%2Fgo-enrichable-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuvava%2Fgo-enrichable-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuvava%2Fgo-enrichable-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuvava%2Fgo-enrichable-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shuvava","download_url":"https://codeload.github.com/shuvava/go-enrichable-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuvava%2Fgo-enrichable-client/sbom","scorecard":{"id":821797,"data":{"date":"2025-08-11","repo":{"name":"github.com/shuvava/go-enrichable-client","commit":"796c68e23e6c7cc39d408d168952bacf26c506d5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T15:47:20.725Z","repository_id":57619406,"created_at":"2025-08-23T15:47:20.725Z","updated_at":"2025-08-23T15:47:20.725Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34573729,"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-06-20T02:00:06.407Z","response_time":98,"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":["cloud","golang","http","rest"],"created_at":"2024-11-10T10:07:35.665Z","updated_at":"2026-06-20T14:31:45.094Z","avatar_url":"https://github.com/shuvava.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Enrichable http client\n\n[![GoDoc](https://godoc.org/github.com/shuvava/go-enrichable-client?status.svg)](http://godoc.org/github.com/shuvava/go-enrichable-client)\n[![Build Status](https://travis-ci.com/shuvava/go-enrichable-client.svg?branch=master)](https://travis-ci.com/shuvava/go-enrichable-client)\n[![Coverage Status](https://coveralls.io/repos/github/shuvava/go-enrichable-client/badge.svg?branch=master)](https://coveralls.io/github/shuvava/go-enrichable-client?branch=master)\n\nthe `go-enrichable-client` package is wrapper over the standard `net/http` client library \nallowing to enrich it functionality by using middleware extensions.\n\n\n## Installation\n\n```shell\ngo get github.com/shuvava/go-enrichable-client\n```\n\n## Usage\n\n**Example of pure http.client usage**\n\n```go\npackage main\n\nimport \"github.com/shuvava/go-enrichable-client/client\"\n\nfunc main() {\n  var responseObject ResponseObject\n  // make GET request and deserialize response body \n  // using default http client with with idle connections \n  // and keepalives disabled.\n  err := client.Get(url, \u0026responseObject)\n  ...\n}\n```\n\n## Creating custom middleware\n\n```go\npackage main\n\nimport (\n  \"net/http\"\n\n  \"github.com/shuvava/go-enrichable-client/client\"\n  \"github.com/shuvava/go-enrichable-client/middleware\"\n)\n\nfunc main() {\n  // create enriched client\n  c := client.DefaultClient()\n  // add custom middleware\n  c.Use(\n  func(c *http.Client, next client.Responder) client.Responder {\n    return func(request *http.Request) (*http.Response, error) {\n      // logic before doing request    \n      res, err:= next(request)\n      // logic after doing request\n      return res, err\n    }\n  })\n  ...\n}\n\n```\n\n## Middleware \n\n|      Name      | Description                                   |\n|:--------------:|:----------------------------------------------|\n|     Retry      | add retry functionality                       |\n|     OAuth      | add bearer authorization token to all request |\n| CircuitBreaker | add Circuit Breaker to all request            |\n|   UserAgent    | add User-Agent header to all requests         |\n\n### Retry middleware\n\nThis middleware adds retry functionality with automatic retries and exponential backoff policy. Currently, package supports only json content type\n\n#### Example usage retryable client\n\n```go\npackage main\n\nimport (\n\t\"github.com/shuvava/go-enrichable-client/client\"\n  \"github.com/shuvava/go-enrichable-client/middleware\"\n)\n\nfunc main() {\n  ...\n\t// create enriched client\n  c := client.DefaultClient()\n  // add retry middleware\n  c.Use(middleware.Retry())\n  // receive reference to http.Client\n  err := c.Get(url, \u0026responseObject)\n  ...\n}\n```\n\n### OAuth middleware\n\nWith machine-to-machine (M2M) applications, such as CLIs, daemons, or services running on your back-end, the system authenticates and authorizes the app rather than a user. For this scenario, typical authentication schemes like username + password or social logins don't make sense. Instead, M2M apps use the Client Credentials Flow (defined in OAuth 2.0 RFC 6749, section 4.4), in which they pass along their Client ID and Client Secret to authenticate themselves and get a token.\n\n#### Example usage oauth client\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"github.com/shuvava/go-enrichable-client/client\"\n  \"github.com/shuvava/go-enrichable-client/middleware\"\n)\n\nfunc main() {\n  ...\n\t// create enriched client\n  c := client.DefaultClient()\n  // add oauth middleware\n  tenant := \"00000000-0000-0000-0000-000000000000\"\n  uri := fmt.Sprintf(\"https://login.microsoftonline.com/%s/oauth2/v2.0/token\", tenant)\n  oauthConifg := middleware.OAuthConfig{\n    AuthServerURL: uri,\n    ClientID:      \"00000000-0000-0000-0000-000000000000\",\n    ClientSecret:  \"some secret\",\n    Scope:         \"api://00000000-0000-0000-0000-000000000000/.default\",\n  }\n  c.Use(middleware.OAuth(oauthConifg))\n  ...\n}\n```\n\n### CircuitBreaker middleware\n\nThe Circuit Breaker pattern can prevent an application repeatedly trying to execute an operation that is likely to fail, allowing it to continue without waiting for the fault to be rectified or wasting CPU cycles while it determines that the fault is long lasting. The Circuit Breaker pattern also enables an application to detect whether the fault has been resolved. If the problem appears to have been rectified, the application can attempt to invoke the operation.\n\nou can configure `CircuitBreaker` by the struct `Settings`:\n\n```go\ntype CircuitBreakerSettings struct {\n\tMaxRequests   uint32\n\tInterval      time.Duration\n\tTimeout       time.Duration\n\tReadyToTrip   func(counts Counts) bool\n\tOnStateChange func(name string, from State, to State)\n}\n```\n\n- `MaxRequests` is the maximum number of requests allowed to pass through\n  when the `CircuitBreakerService` is half-open.\n  If `MaxRequests` is 0, `CircuitBreakerService` allows only 1 request.\n- `Interval` is the cyclic period of the closed state\n  for `CircuitBreaker` to clear the internal `Counts`, described later in this section.\n  If `Interval` is 0, `CircuitBreakerService` doesn't clear the internal `Counts` during the closed state.\n- `Timeout` is the period of the open state,\n  after which the state of `CircuitBreakerService` becomes half-open.\n  If `Timeout` is 0, the timeout value of `CircuitBreakerService` is set to 60 seconds.\n- `ReadyToTrip` is called with a copy of `Counts` whenever a request fails in the closed state.\n  If `ReadyToTrip` returns true, `CircuitBreakerService` will be placed into the open state.\n  If `ReadyToTrip` is `nil`, default `ReadyToTrip` is used.\n  Default `ReadyToTrip` returns true when the number of consecutive failures is more than 5.\n- `OnStateChange` is called whenever the state of `CircuitBreakerService` changes.\nThe struct `CircuitBreakerCounts` holds the numbers of requests and their successes/failures:\n\n```go\ntype CircuitBreakerCounts struct {\n\tRequests             uint32\n\tTotalSuccesses       uint32\n\tTotalFailures        uint32\n\tConsecutiveSuccesses uint32\n\tConsecutiveFailures  uint32\n}\n```\n\n`CircuitBreakerService` clears the internal `CircuitBreakerCounts` either\non the change of the state or at the closed-state intervals.\n`CircuitBreakerCounts` ignores the results of the requests sent before clearing.\n\n#### Example usage oauth client\n\n```go\npackage main\n\nimport (\n  \"github.com/shuvava/go-enrichable-client/client\"\n  \"github.com/shuvava/go-enrichable-client/middleware\"\n)\n\nfunc main() {\n  ...\n  // create enriched http client\n  c := client.DefaultClient()\n  // add circuit breaker middleware\n  c.Use(middleware.CircuitBreaker(middleware.CircuitBreakerSettings{}))\n  ...\n}\n```\n\n### UserAgent middleware\n\nUserAgent is a middleware that add the user agent string into request http.Header.\n\n#### Example usage UserAgent middleware\n\n```go\npackage main\n\nimport (\n  \"github.com/shuvava/go-enrichable-client/client\"\n  \"github.com/shuvava/go-enrichable-client/middleware\"\n)\n\nfunc main() {\n  ...\n  // create enriched http client\n  c := client.DefaultClient()\n  // add user-agent middleware\n  c.Use(middleware.UserAgent(middleware.UserAgentConfig{App: \"app-name\", Version: \"1.0.0\"}))\n  ...\n}\n```\n\n## Links \n\n* [AWS error handling](https://docs.aws.amazon.com/apigateway/api-reference/handling-errors/)\n* [hashicorp http client](https://github.com/hashicorp/go-retryablehttp.git)\n* [Circuit Breaker pattern](https://msdn.microsoft.com/en-us/library/dn589784.aspx)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuvava%2Fgo-enrichable-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshuvava%2Fgo-enrichable-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuvava%2Fgo-enrichable-client/lists"}