Skip to content

Commit 79a0b52

Browse files
authored
Add HttpClient guidance (#29568)
1 parent 07534d7 commit 79a0b52

File tree

12 files changed

+76
-28
lines changed

12 files changed

+76
-28
lines changed

docs/architecture/blazor-for-web-forms-developers/data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Whenever you need to access data from GitHub, create a client with a name of `gi
130130
}
131131
```
132132

133-
This method returns the string describing the collection of issues in the *dotnet/docs* GitHub repository. It returns content in JSON format and is deserialized into appropriate GitHub issue objects. There are many ways that you can configure the `HttpClientFactory` to deliver preconfigured `HttpClient` objects. Try configuring multiple `HttpClient` instances with different names and endpoints for the various web services you work with. This approach will make your interactions with those services easier to work with on each page. For more details, read [the documentation for the IHttpClientFactory](/aspnet/core/fundamentals/http-requests).
133+
This method returns the string describing the collection of issues in the *dotnet/docs* GitHub repository. It returns content in JSON format and is deserialized into appropriate GitHub issue objects. There are many ways that you can configure the `HttpClientFactory` to deliver preconfigured `HttpClient` objects. Try configuring multiple `HttpClient` instances with different names and endpoints for the various web services you work with. This approach will make your interactions with those services easier to work with on each page. For more information, see [Make HTTP requests using IHttpClientFactory](/aspnet/core/fundamentals/http-requests).
134134

135135
>[!div class="step-by-step"]
136136
>[Previous](forms-validation.md)

docs/architecture/cloud-native/application-resiliency-patterns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.date: 04/06/2022
1111

1212
The first line of defense is application resiliency.
1313

14-
While you could invest considerable time writing your own resiliency framework, such products already exist. [Polly](https://dotnetfoundation.org/projects/polly) is a comprehensive .NET resilience and transient-fault-handling library that allows developers to express resiliency policies in a fluent and thread-safe manner. Polly targets applications built with either the .NET Framework or .NET 6. The following table describes the resiliency features, called `policies`, available in the Polly Library. They can be applied individually or grouped together.
14+
While you could invest considerable time writing your own resiliency framework, such products already exist. [Polly](https://dotnetfoundation.org/projects/polly) is a comprehensive .NET resilience and transient-fault-handling library that allows developers to express resiliency policies in a fluent and thread-safe manner. Polly targets applications built with either .NET Framework or .NET 6. The following table describes the resiliency features, called `policies`, available in the Polly Library. They can be applied individually or grouped together.
1515

1616
| Policy | Experience |
1717
| :-------- | :-------- |

docs/architecture/dapr-for-net-developers/reference-application.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ public class CatalogService : ICatalogService
381381
}
382382
```
383383

384-
Notice how no Dapr specific code is required to make the service invocation call. All communication is done using the standard HttpClient object.
384+
Notice how no Dapr-specific code is required to make the service invocation call. All communication is done using the standard HttpClient object.
385385

386386
The Dapr HttpClient is configured for the `CatalogService` class on program startup:
387387

docs/architecture/microservices/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ The following steps show how you can use Http retries with Polly integrated into
1616

1717
**Reference the .NET 6 packages**
1818

19-
`IHttpClientFactory` is available since .NET Core 2.1 however we recommend you to use the latest .NET 6 packages from NuGet in your project. You typically also need to reference the extension package `Microsoft.Extensions.Http.Polly`.
19+
`IHttpClientFactory` is available since .NET Core 2.1, however, we recommend you use the latest .NET 6 packages from NuGet in your project. You typically also need to reference the extension package `Microsoft.Extensions.Http.Polly`.
2020

2121
**Configure a client with Polly's Retry policy, in Startup**
2222

23-
As shown in previous sections, you need to define a named or typed client HttpClient configuration in your standard Startup.ConfigureServices(...) method, but now, you add incremental code specifying the policy for the Http retries with exponential backoff, as below:
23+
As shown in previous sections, you need to define a named or typed client HttpClient configuration in your standard `Startup.ConfigureServices(...)` method, but now, you add incremental code specifying the policy for the Http retries with exponential backoff, as below:
2424

2525
```csharp
2626
//ConfigureServices() - Startup.cs

docs/architecture/modernize-desktop/migrate-modern-applications.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Second, you'll need to regenerate the service client with the new tools present
164164

165165
After the migration, if you find that there are libraries you need that aren't present on .NET, you can add a reference to the [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) NuGet package and see if the missing functions are there.
166166

167-
If you're using the <xref:System.Net.WebRequest> class to perform web service calls, you may find some differences on .NET. The recommendation is to use the System.Net.Http.HttpClient instead.
167+
If you're using the <xref:System.Net.WebRequest> class to perform web service calls, you may find some differences on .NET. The recommendation is to use <xref:System.Net.Http.HttpClient> instead.
168168

169169
## Consuming a COM Object
170170

docs/core/extensions/http-client.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
---
2-
title: HTTP with .NET
2+
title: IHttpClientFactory with .NET
33
description: Learn how to use the HttpClient and IHttpClientFactory implementations with dependency injection in your .NET workloads.
44
author: IEvangelist
55
ms.author: dapine
66
ms.date: 11/12/2021
77
---
88

9-
# HTTP with .NET
9+
# IHttpClientFactory with .NET
1010

1111
In this article, you'll learn how to use the `IHttpClientFactory` and the `HttpClient` types with various .NET fundamentals, such as dependency injection (DI), logging, and configuration. The <xref:System.Net.Http.HttpClient> type was introduced in .NET Framework 4.5, which was released in 2012. In other words, it's been around for a while. `HttpClient` is used for making HTTP requests and handling HTTP responses from web resources identified by a <xref:System.Uri>. The HTTP protocol makes up the vast majority of all internet traffic.
1212

1313
With modern application development principles driving best practices, the <xref:System.Net.Http.IHttpClientFactory> serves as a factory abstraction that can create `HttpClient` instances with custom configurations. <xref:System.Net.Http.IHttpClientFactory> was introduced in .NET Core 2.1. Common HTTP-based .NET workloads can take advantage of resilient and transient-fault-handling third-party middleware with ease.
1414

15-
## Explore the `IHttpClientFactory` type
15+
> [!NOTE]
16+
> If your app requires cookies, it might be better not to use <xref:System.Net.Http.IHttpClientFactory> in your app. For alternative ways of managing clients, see [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).
1617
17-
All of the sample source code in this article relies on the [`Microsoft.Extensions.Http`](https://www.nuget.org/packages/microsoft.extensions.http) NuGet package. Additionally, [The Internet Chuck Norris Database](https://www.icndb.com) free API is used to make HTTP GET requests for "nerdy" jokes.
18+
## The `IHttpClientFactory` type
19+
20+
All of the sample source code in this article relies on the [`Microsoft.Extensions.Http`](https://www.nuget.org/packages/microsoft.extensions.http) NuGet package. Additionally, [The Internet Chuck Norris Database](https://www.icndb.com) free API is used to make HTTP `GET` requests for "nerdy" jokes.
1821

1922
When you call any of the <xref:Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions.AddHttpClient%2A> extension methods, you're adding the `IHttpClientFactory` and related services to the <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection>. The `IHttpClientFactory` type offers the following benefits:
2023

@@ -145,16 +148,16 @@ The defined interface can be consumed where necessary, with the implementation p
145148

146149
## Make POST, PUT, and DELETE requests
147150

148-
In the preceding examples, all HTTP requests use the GET HTTP verb. `HttpClient` also supports other HTTP verbs, including:
151+
In the preceding examples, all HTTP requests use the `GET` HTTP verb. `HttpClient` also supports other HTTP verbs, including:
149152

150-
- POST
151-
- PUT
152-
- DELETE
153-
- PATCH
153+
- `POST`
154+
- `PUT`
155+
- `DELETE`
156+
- `PATCH`
154157

155158
For a complete list of supported HTTP verbs, see <xref:System.Net.Http.HttpMethod>.
156159

157-
The following example shows how to make an HTTP POST request:
160+
The following example shows how to make an HTTP `POST` request:
158161

159162
:::code source="snippets/http/basic/ItemService.cs" id="Create":::
160163

@@ -167,13 +170,13 @@ In the preceding code, the `CreateItemAsync` method:
167170

168171
`HttpClient` also supports other types of content. For example, <xref:System.Net.Http.MultipartContent> and <xref:System.Net.Http.StreamContent>. For a complete list of supported content, see <xref:System.Net.Http.HttpContent>.
169172

170-
The following example shows an HTTP PUT request:
173+
The following example shows an HTTP `PUT` request:
171174

172175
:::code source="snippets/http/basic/ItemService.cs" id="Update":::
173176

174-
The preceding code is very similar to the POST example. The `UpdateItemAsync` method calls <xref:System.Net.Http.HttpClient.PutAsync%2A> instead of `PostAsync`.
177+
The preceding code is very similar to the `POST` example. The `UpdateItemAsync` method calls <xref:System.Net.Http.HttpClient.PutAsync%2A> instead of `PostAsync`.
175178

176-
The following example shows an HTTP DELETE request:
179+
The following example shows an HTTP `DELETE` request:
177180

178181
:::code source="snippets/http/basic/ItemService.cs" id="Delete":::
179182

@@ -199,7 +202,7 @@ services.AddHttpClient("Named.Client")
199202
> [!IMPORTANT]
200203
> You can generally treat `HttpClient` instances as objects that **do not** require disposal. Disposal cancels outgoing requests and guarantees the given `HttpClient` instance can't be used after calling <xref:System.IDisposable.Dispose%2A>. `IHttpClientFactory` tracks and disposes resources used by `HttpClient` instances.
201204
202-
Keeping a single `HttpClient` instance alive for a long duration is a common pattern used before the inception of `IHttpClientFactory`. This pattern becomes unnecessary after migrating to `IHttpClientFactory`.
205+
Keeping a single `HttpClient` instance alive for a long duration is a common pattern used before the inception of `IHttpClientFactory`. For information about which strategy to use in your app, see [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).
203206

204207
## Configure the `HttpMessageHandler`
205208

docs/core/tools/dotnet-environment-variables.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ The `AppContext` switch can also be set by a config file. For more information c
108108

109109
The same can be achieved via the environment variable `DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER`. To opt-out, set the value to either `false` or `0`.
110110

111+
> [!NOTE]
112+
> Starting in .NET 5, this setting to use <xref:System.Net.Http.HttpClientHandler> is no longer available.
113+
111114
### `DOTNET_Jit*` and `DOTNET_GC*`
112115

113116
There are two stressing-related features for the JIT and JIT-generated GC information: JIT Stress and GC Hole Stress. These features provide a way during development to discover edge cases and more "real world" scenarios without having to develop complex applications. The following environment variables are available:

docs/framework/wcf/whats-new.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ Support has been added to allow for WCF services with Internationalized Domain N
118118

119119
## HttpClient
120120

121-
A new class called <xref:System.Net.Http.HttpClient> has been added to make working with HTTP requests much easier. For more info, see [HTTP with .NET](../../core/extensions/http-client.md).
121+
A new class called <xref:System.Net.Http.HttpClient> has been added to make working with HTTP requests much easier. For more info, see <xref:System.Net.Http.HttpClient> and [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).
122122

123123
## Configuration IntelliSense
124124

docs/fundamentals/index.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ landingContent:
152152
url: ../core/extensions/workers.md
153153
- text: Caching in .NET
154154
url: ../core/extensions/caching.md
155-
- text: HTTP with .NET
156-
url: ../core/extensions/http-client.md
155+
- text: HTTP in .NET
156+
url: networking/httpclient-guidelines.md
157157
- text: Localization in .NET
158158
url: ../core/extensions/localization.md
159159
- text: File globbing in .NET
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: HttpClient guidelines for .NET
3+
description: Learn about using HttpClient instances to send HTTP requests and how you can manage clients using IHttpClientFactory in your .NET apps.
4+
author: gewarren
5+
ms.author: gewarren
6+
ms.date: 05/19/2022
7+
---
8+
# Guidelines for using HttpClient
9+
10+
The <xref:System.Net.Http.HttpClient?displayProperty=fullName> class sends HTTP requests and receives HTTP responses from a resource identified by a URI. An <xref:System.Net.Http.HttpClient> instance is a collection of settings that's applied to all requests executed by that instance, and each instance uses its own connection pool, which isolates its requests from others. Starting in .NET Core 2.1, the <xref:System.Net.Http.SocketsHttpHandler> class provides the implementation, making behavior consistent across all platforms.
11+
12+
If you're using .NET 5+ (including .NET Core), there are some considerations to keep in mind if you're using <xref:System.Net.Http.HttpClient>.
13+
14+
## DNS behavior
15+
16+
<xref:System.Net.Http.HttpClient> only resolves DNS entries when a connection is created. It does not track any time to live (TTL) durations specified by the DNS server. If DNS entries change regularly, which can happen in some container scenarios, the client won't respect those updates. To solve this issue, you can limit the lifetime of the connection by setting the <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> property, so that DNS lookup is required when the connection is replaced.
17+
18+
## Pooled connections
19+
20+
In .NET Framework, disposing <xref:System.Net.Http.HttpClient> objects does not impact connection management. However, in .NET Core, the connection pool is linked to the client's underlying <xref:System.Net.Http.HttpMessageHandler>. When the <xref:System.Net.Http.HttpClient> instance is disposed, it disposes all previously used connections. If you later send a request to the same server, a new connection is created. There's also a performance penalty because it needs a new TCP port. If the rate of requests is high, or if there are any firewall limitations, that can **exhaust the available sockets** because of default TCP cleanup timers.
21+
22+
## Recommended use
23+
24+
- In .NET Framework, you can create a new <xref:System.Net.Http.HttpClient> each time you need to send a request.
25+
- In .NET Core and .NET 5+:
26+
- Use a static or singleton <xref:System.Net.Http.HttpClient> with <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> set to a desired interval, such as two minutes, depending on expected DNS changes. This solves both the socket exhaustion and DNS changes problems without adding the overhead of <xref:System.Net.Http.IHttpClientFactory>. If you need to be able to mock your handler, you can register it separately.
27+
- Using <xref:System.Net.Http.IHttpClientFactory>, you can have multiple, differently configured clients for different use cases. If its lifetime hasn't expired, an <xref:System.Net.Http.HttpMessageHandler> instance may be reused from the pool when the factory creates a new <xref:System.Net.Http.HttpClient> instance. This reuse avoids any socket exhaustion issues. If you desire the configurability that <xref:System.Net.Http.IHttpClientFactory> provides, we recommend using the [typed-client approach](../../core/extensions/http-client.md#typed-clients). However, be aware that the clients created by the factory are intended to be short-lived, and once the client is created, the factory no longer has control over it.
28+
29+
> [!TIP]
30+
> If your app requires cookies, consider disabling automatic cookie handling or avoiding <xref:System.Net.Http.IHttpClientFactory>. Pooling the <xref:System.Net.Http.HttpMessageHandler> instances results in sharing of <xref:System.Net.CookieContainer> objects. Unanticipated <xref:System.Net.CookieContainer> object sharing often results in incorrect code.
31+
32+
## See also
33+
34+
- [Make HTTP requests using IHttpClientFactory](/aspnet/core/fundamentals/http-requests)
35+
- [Use IHttpClientFactory to implement resilient HTTP requests](../../architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md)

docs/fundamentals/toc.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,10 +2496,15 @@ items:
24962496
href: ../core/extensions/console-log-formatter.md
24972497
- name: HostBuilder (generic host)
24982498
href: ../core/extensions/generic-host.md
2499-
- name: HTTP with .NET
2500-
href: ../core/extensions/http-client.md
2501-
- name: HTTP/3 with .NET
2502-
href: ../core/extensions/httpclient-http3.md
2499+
- name: Networking
2500+
items:
2501+
- name: HTTP clients in .NET
2502+
displayName: networking, httpclient
2503+
href: networking/httpclient-guidelines.md
2504+
- name: IHttpClientFactory
2505+
href: ../core/extensions/http-client.md
2506+
- name: HTTP/3 with .NET
2507+
href: ../core/extensions/httpclient-http3.md
25032508
- name: File globbing in .NET
25042509
href: ../core/extensions/file-globbing.md
25052510
- name: Primitives library in .NET

docs/standard/runtime-libraries-overview.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ Some libraries are provided in NuGet packages rather than included in the runtim
2424
| [Dependency injection](../core/extensions/dependency-injection.md) | [`Microsoft.Extensions.DependencyInjection`][di] |
2525
| [File globbing](../core/extensions/file-globbing.md) | [`Microsoft.Extensions.FileSystemGlobbing`][fsg] |
2626
| [Generic Host](../core/extensions/generic-host.md) | [`Microsoft.Extensions.Hosting`][host] |
27-
| [HTTP](../core/extensions/http-client.md) | [`Microsoft.Extensions.Http`][http] |
27+
| [HTTP](../core/extensions/http-client.md) | [`Microsoft.Extensions.Http`]<sup>1</sup>[http] |
2828
| [Localization](../core/extensions/localization.md) | [`Microsoft.Extensions.Localization`][loc] |
2929
| [Logging](../core/extensions/logging.md) | [`Microsoft.Extensions.Logging`][log] |
3030

31+
<sup>1</sup>For some target frameworks, including `net6.0`, these types are part of the shared framework and don't need to be installed separately.
32+
3133
[configuration]: https://www.nuget.org/packages/Microsoft.Extensions.Configuration
3234
[di]: https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection
3335
[fsg]: https://www.nuget.org/packages/Microsoft.Extensions.FileSystemGlobbing

0 commit comments

Comments
 (0)