{"id":21730082,"url":"https://github.com/nventive/httpclientutilities","last_synced_at":"2026-05-17T22:34:05.110Z","repository":{"id":98348590,"uuid":"198291439","full_name":"nventive/HttpClientUtilities","owner":"nventive","description":"Utilities for .NET HttpClient.","archived":false,"fork":false,"pushed_at":"2019-07-22T20:18:09.000Z","size":47,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-26T23:51:29.453Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","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/nventive.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2019-07-22T19:44:10.000Z","updated_at":"2019-07-22T20:18:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"8919daa5-1b52-4ecb-99c4-1eef45c859e2","html_url":"https://github.com/nventive/HttpClientUtilities","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nventive%2FHttpClientUtilities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nventive%2FHttpClientUtilities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nventive%2FHttpClientUtilities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nventive%2FHttpClientUtilities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nventive","download_url":"https://codeload.github.com/nventive/HttpClientUtilities/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244706724,"owners_count":20496614,"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":[],"created_at":"2024-11-26T04:11:49.734Z","updated_at":"2026-05-17T22:34:05.060Z","avatar_url":"https://github.com/nventive.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HttpClientUtilities\n\nUtilities for .NET `HttpClient`.\n\nThis projects provides utilities to implement resilient and manageable components\nthat uses `HttpClient`. In particular, it provides:\n- a Fluent URI builder\n- standard `Options` for configuring `HttpClient` that integrated with [`Polly`](http://www.thepollyproject.org/)\n- a `DelegatingHandler` that allows complete tracing of requests and responses, including the body\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n[![Build Status](https://dev.azure.com/nventive-public/nventive/_apis/build/status/nventive.HttpClientUtilities?branchName=master)](https://dev.azure.com/nventive-public/nventive/_build/latest?definitionId=4\u0026branchName=master)\n![Nuget](https://img.shields.io/nuget/v/HttpClientUtilities.svg)\n\n## Getting Started\n\nInstall the package:\n\n```\nInstall-Package HttpClientUtilities\n```\n\nThen the various features can be used independently. However, they are designed\nto work in conjunction with the [`IHttpClientFactory`](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2).\n\n## Features\n\n### FluentUriBuilder\n\nThe `FluentUriBuilder` is designed to help build composable Uri when calling APIs.\n\nHere is an example:\n\n```csharp\n\nusing HttpClientUtilities;\n\nFluentUriBuilder\n  .ForPath(\"api\")                     // The base Uri\n  .WithSegment(\"users\")               // Adds a Uri segment\n  .WithParam(\"username\", \"John Doe\")  // Adds a query string parameter, encoded\n  .WithFragment(\"anchor-point\");      // Sets the Uri fragment\n  // This will produce \"api/users?username=John+Doe#anchor-point.\"\n```\n\nPlease refer to the documentation for each method for more information.\n\nThe `FluentUriBuilder` is immutable, which means each method returns a new immutable \ninstance that can be independently re-used:\n\n```csharp\n\nvar baseBuilder = FluentUriBuilder\n  .ForPath(\"api\")\n  .WithSegment(\"users\");\n\nbaseBuilder.WithParam(\"username\", \"John Doe\"); // \"api/users?username=John+Doe\"\nbaseBuilder.WithParam(\"foo\", \"bar\"); // \"api/users?foo=bar\"\n```\n\nIt also implicitly casts to a `System.Uri`:\n\n```csharp\nUri uri = FluentUriBuilder.ForPath(\"api/users\");\n\n// This works as well\nHttpClient client;\nvar response = await client.GetAsync(FluentUriBuilder.ForPath(\"api/users\"));\n```\n\nAdditional extension methods can be added to the `FluentUriBuilder` class to\nprovide your own custom behavior:\n\n```csharp\nusing System;\nusing System.Globalization;\n\nnamespace HttpClientUtilities\n{\n    public static class FluentUriBuilderExtensions\n    {\n        /// \u003csummary\u003e\n        /// Adds a \u003csee cref=\"DateTimeOffset\"/\u003e as a query string parameter by formatting it as UTC ISO.\n        /// \u003c/summary\u003e\n        public static FluentUriBuilder WithParam(this FluentUriBuilder buidler, string name, DateTimeOffset date)\n            =\u003e buidler.WithParam(name, date.UtcDateTime.ToString(\"o\", CultureInfo.InvariantCulture), encode: false);\n    }\n}\n```\n\n### Request/Response Tracing\n\nWhen configuring the `HttpClient` via the factory, add the tracing handler:\n\n```csharp\n\nusing Microsoft.Extensions.DependencyInjection;\n\n\nservices\n    .AddHttpClient\u003cMyNamedClient\u003e() // Adds a named HttpClient\n    .AddHttpTracing\u003cMyNamedClient\u003e(); // Attaches a named tracing handler.\n```\n\nThe tracing handler (`AddHttpTracing`) should probably be the last handler in the\nchain in order to capture all modifications done by other handlers if they exist.\n\nThe logger category [follows the conventions defined by the `IHttpClientFactory`](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2#logging)\nby naming the category `System.Net.Http.HttpClient.MyNamedClient.TraceHandler`.\n\nEvent ids used for the various messages:\n\n| Event id | Event Name         | Log level | Description                         |\n|----------|--------------------|-----------|-------------------------------------|\n| 200      | RequestSuccessful  | Trace     | Request trace on successful calls   |\n| 201      | RequestError       | Warning   | Request trace on unsuccessful calls |\n| 210      | ResponseSuccessful | Trace     | Response on successful calls        |\n| 211      | ResponseError      | Warning   | Response on unsuccessful calls      |\n\nA successful call is determined by default using `HttpResponseMessage.IsSuccessStatusCode`.\nThis can be customized when adding the handler:\n\n```csharp\nservices\n    .AddHttpClient\u003cMyNamedClient\u003e()\n    .AddHttpTracing\u003cMyNamedClient\u003e(\n        response =\u003e response.StatusCode \u003e= HttpStatusCode.InternalServerError);\n```\n\n#### Using with Application Insights\n\nBy default, Application Insights captures only `Warning` and `Error` log levels.\nTo enable tracing of successful requests and responses, [configure the log level for Application Insights](https://docs.microsoft.com/en-us/azure/azure-monitor/app/ilogger). \nExample within the `appsettings.json` file:\n\n```json\n{\n  \"Logging\": {\n    \"ApplicationInsights\": {\n      \"LogLevel\": {\n        \"System.Net.Http.HttpClient.MyNamedClient.TraceHandler\": \"Trace\"\n      }\n    },\n  }\n}\n```\n\n### Default options for HTTP and Polly configuration\n\n[Polly](http://www.thepollyproject.org/) is a great library with integration with\nthe `IHttpClientFactory` and helps tremendously to provide good strategies to handle\ntransient errors (retries, circuit breaker...).\n\nUnfortunately, by default it does not provide a configuration model that is\nintegrated with the [ASP.NET Core Configuration model](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2).\n\nThis library fills the gap by providing:\n\n- a base class for `HttpOptions` that can be used to specify properties for Polly policies\n- helpers extension methods to configure the `HttpClient` automatically\n\nThis strategy adds the following configurable behaviors:\n\n- Request timeouts\n- Automatic retries, with a [jittered sleep strategy](https://github.com/App-vNext/Polly/wiki/Retry-with-jitter)\n- Circuit breaker\n- The possibility to restrict the number of requests issued in parallel\n- The possibility to configure default headers\n- Sensible default for User-Agent if not configured\n\nTo use this feature:\n\n1. Create an Options class for your client that derives from `HttpOptions`:\n\n```csharp\nusing HttpClientUtilities;\n\npublic class GitHubServiceOptions : HttpOptions\n{\n    // Additional configurations goes here if needed.\n}\n```\n\n2. Create you Component that uses the `HttpClient` ([following the standard `IHttpClientFactory` usage](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2)):\n\n```csharp\npublic class GitHubService\n{\n    public GitHubService(HttpClient client)\n    {\n        // ...\n    }\n}\n```\n\n3. Register the options and client using extension methods:\n\n```csharp\nservices\n    // Configure the options (in this case by loading it from the configuration)\n    .Configure\u003cGitHubServiceOptions\u003e(configuration.GetSection(nameof(GitHubServiceOptions)))\n    // Register the service\n    .AddTransient\u003cGitHubService\u003e()\n    // Register the named HttpClient and apply HttpClient configuration\n    .AddAndConfigureHttpClient\u003cGitHubService, GitHubServiceOptions\u003e()\n    // Adds Polly policies configured in the options\n    .AddPoliciesFromOptions\u003cGitHubServiceOptions\u003e();\n\n```\n\n4. Configure the behaviors using the options, for example here in the `appsettings.json`:\n\n```json\n{\n  \"GitHubServiceOptions\": {\n    \"BaseAddress\": \"https://api.github.com\",\n    \"Timeout\": \"00:00:05\",\n    \"Headers\": {\n      \"Authorization\": \"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\",\n      \"User-Agent\": \"MyUserAgent/1.0 (dev)\"\n    },\n    \"NumberOfRetries\": 2,\n    \"RetriesSleepDuration\": \"00:00:00.100\",\n    \"RetriesMaximumSleepDuration\": \"00:00:01\",\n    \"ErrorsAllowedBeforeBreaking\": 5,\n    \"BreakDuration\": \"01:00:00\",\n    \"MaxParallelization\": 10\n  }\n}\n```\n\nThe following defaults are applied when using `HttpOptions` without overriding the values:\n\n| Parameter                   | Default Value    | Description                                                                                          |\n|-----------------------------|------------------|------------------------------------------------------------------------------------------------------|\n| Timeout                     | 30 seconds       | The request timeout.                                                                                 |\n| NumberOfRetries             | 3                | Number of automatic retries on transient HTTP errors. Set to 0 to disable automatic retries.         |\n| RetriesSleepDuration        | 300 milliseconds | Minimum sleep duration between retries.                                                              |\n| RetriesMaximumSleepDuration | 3 seconds        | Maximum sleep duration between retries. Set to 00:00:00 to have a fixed RetriesSleepDuration.        |\n| ErrorsAllowedBeforeBreaking | 10               | Number of errors to allow before the Circuit Breaker opens. Set to 0 to disable the Circuit Breaker. |\n| BreakDuration               | 1 minute         | Duration of a break when the circuit breaker opens.                                                  |\n| MaxParallelization          | 0                | Maximum number of parallel requests allowed (in flight). Set to 0 for unlimited parallel requests.   |\n| Headers / User-Agent        | \"{0}/{1} ({2})\"  | 0: options Assembly name, 1: options Assembly version, 2: IHostingEnvironment.EnvironmentName        |\n\n\n\n## Changelog\n\nPlease consult the [CHANGELOG](CHANGELOG.md) for more information about version\nhistory.\n\n## License\n\nThis project is licensed under the Apache 2.0 license - see the\n[LICENSE](LICENSE) file for details.\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the process for\ncontributing to this project.\n\nBe mindful of our [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Acknowledgments\n\n- [Polly](http://www.thepollyproject.org/)\n- [Flurl](https://flurl.dev/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnventive%2Fhttpclientutilities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnventive%2Fhttpclientutilities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnventive%2Fhttpclientutilities/lists"}