La forma correcta de utilizar HttpClient en .NET
Si estás construyendo una aplicación en .NET, es probable que necesites llamar a una API externa a través de HTTP.
La forma fácil de hacer solicitudes HTTP en .NET es utilizar HttpClient para enviar esas solicitudes. Y es una gran abstracción para trabajar, especialmente con los métodos que admiten cargas útiles y respuestas JSON.
Desafortunadamente, es fácil abusar de HttpClient.
El agotamiento de puertos y el comportamiento del DNS son algunos de los problemas más comunes.
Entonces, aquí tienes lo que necesitas saber sobre cómo trabajar con HttpClient:
Cómo no usar HttpClient
Cómo simplificar la configuración con IHttpClientFactory
Cómo configurar typed clients
Por qué debes evitar clientes tipados en servicios singleton
Cuando usar cada opción
La forma sencilla de usar HttpClient
La forma más sencilla de trabajar con HttpClient es simplemente crear una nueva instancia, configurar las propiedades requeridas y usarla para enviar solicitudes.
¿Qué podría salir mal?
Las instancias de HttpClient están diseñadas para ser duraderas y reutilizadas a lo largo de la vida de la aplicación.
Cada instancia utiliza su propia pool de conexiones con fines de aislamiento, pero también para evitar el agotamiento de puertos. Si un servidor está bajo una carga alta y tu aplicación está creando constantemente nuevas conexiones, podría llevar al agotamiento de los puertos disponibles. Esto causará una excepción en tiempo de ejecución al intentar enviar una solicitud.
Entonces, ¿Cómo puedes evitar esto?
La forma inteligente de crear HttpClient utilizando IHttpClientFactory
En lugar de gestionar tú mismo el ciclo de vida de HttpClient, puedes utilizar un IHttpClientFactory para crear la instancia de HttpClient.
Simplemente llama al método CreateClient y utiliza la instancia de HttpClient devuelta para enviar tus solicitudes HTTP.
¿Por qué es este un enfoque mejor?
La parte costosa de HttpClient es el manejador de mensajes real: HttpMessageHandler. Cada HttpMessageHandler tiene un pool de conexiones HTTP interna que puede reutilizarse.
IHttpClientFactory almacenará en caché el HttpMessageHandler y lo reutilizará al crear una nueva instancia de HttpClient.
Un punto importante aquí es que las instancias de HttpClient creadas por IHttpClientFactory están destinadas a tener una vida corta.
Reduciendo la duplicación de código con named clients
El uso de IHttpClientFactory resolverá la mayoría de los problemas de crear manualmente un HttpClient. Sin embargo, aún necesitamos configurar los parámetros predeterminados de la solicitud cada vez que obtenemos un nuevo HttpClient del método CreateClient.
Puedes configurar un named client llamando al método AddHttpClient y pasando el nombre deseado. AddHttpClient acepta un delegate que puedes utilizar para configurar los parámetros predeterminados en la instancia de HttpClient.
La principal diferencia ahora es que debes obtener el cliente pasando el nombre del cliente a CreateClient.
Pero el uso del HttpClient parece mucho más sencillo:
Reemplazando named clients con types clients
La desventaja de usar names clients es tener que resolver un HttpClient pasando un nombre cada vez.
Hay una mejor manera de lograr el mismo comportamiento configurando un type client. Puedes hacer esto llamando al método AddClient<TClient> y configurando el servicio que consumirá el HttpClient.
En el fondo, esto sigue utilizando un named client, donde el name es el mismo del type named.
Y esto también registrará GitHubService con una duración transitoria.
Dentro de GitHubService, inyectas y utilizas la instancia tipada de HttpClient que tendrá toda la configuración aplicada.
Ya no tienes que lidiar con IHttpClientFactory y crear instancias de HttpClient manualmente.
Por qué debes evitar Typed Clients en singleton services
Podrías enfrentar un problema si inyectas un typed client en un singleton service. Dado que el typed client es transitorio, inyectarlo en un singleton service hará que se almacene en caché durante toda la vida útil del singleton service
Esto impedirá que el typed client reaccione a cambios en el DNS.
Si deseas utilizar un typed en un singleton service, el enfoque recomendado es utilizar SocketsHttpHandler como manejador principal y configurar PooledConnectionLifetime.
Dado que SocketsHttpHandler manejará el almacenamiento en caché de conexiones, puedes desactivar el reciclaje a nivel de IHttpClientFactory estableciendo HandlerLifetime en Timeout.InfiniteTimeSpan.
¿Cuándo deberías usar cada opción?
Te mostré algunas opciones posibles para trabajar con HttpClient.
Pero, ¿cuál deberías usar y cuándo?
Microsoft tuvo la amabilidad de proporcionarnos un conjunto de mejores prácticas y recomendaciones para el uso de HttpClient.
Utiliza una instancia estática o singleton de HttpClient con PooledConnectionLifetime configurado, ya que esto resuelve tanto el agotamiento de puertos como el seguimiento de cambios en DNS.
Usa IHttpClientFactory si deseas centralizar la configuración en un solo lugar, pero recuerda que los clientes están destinados a tener una vida corta.
Usa un typed client si deseas la configurabilidad de IHttpClientFactory.
Prefiero trabajar con un typed client y soy consciente de que está configurado como un servicio transitorio.








