blazor-httpclient-rest-api-factory

HttpClient en Blazor: consumir APIs con clientes tipados

  • 3 min

HttpClient es la API de .NET para enviar peticiones HTTP y recibir respuestas de servicios remotos.

En Interactive WebAssembly, el código se ejecuta dentro del navegador y necesita una API para acceder a datos del servidor. En SSR o Interactive Server, HttpClient también permite llamar a servicios HTTP internos o externos.

En el servidor debemos gestionar correctamente la reutilización de sus conexiones. En WebAssembly, HttpClient se apoya en la API fetch del navegador.

El problema de new HttpClient()

Instintivamente, podríamos pensar en hacer esto dentro de un servicio:

// ⛔ MAL: No hagas esto en producción
using (var client = new HttpClient())
{
    var response = await client.GetAsync("https://miapi.com/productos");
}
Copied!

En .NET del lado servidor, crear y destruir clientes por petición impide reutilizar correctamente los manejadores y puede provocar agotamiento de puertos o problemas al actualizar DNS.

Para solucionar esto, Microsoft introdujo IHttpClientFactory.

Esta fábrica reutiliza y rota manejadores HTTP, además de permitir configurar clientes de forma centralizada. Para usarla en un proyecto cliente Blazor, añade el paquete Microsoft.Extensions.Http.

Configurar clientes tipados

Una opción cómoda es usar clientes tipados, que encapsulan las llamadas de una API concreta.

Esto vincula una configuración HTTP específica (URL base, cabeceras) a una clase de servicio concreta.

Registro en Program.cs

En lugar de registrar el servicio con AddScoped a secas, usamos AddHttpClient.

// Program.cs

// Registramos el servicio Y configuramos su HttpClient asociado
builder.Services.AddHttpClient<IProductoService, ProductoServiceAPI>(client =>
{
    // Configuramos la URL base. Así el servicio no necesita saber la IP del servidor.
    client.BaseAddress = new Uri("https://api.luisllamas.es/v1/");

    // Podemos añadir cabeceras globales (ej: API Key, User-Agent)
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});
Copied!

Inyección en el servicio

Ahora, en nuestra clase ProductoServiceAPI, inyectamos HttpClient por el constructor. La instancia recibida ya contiene la BaseAddress y los encabezados configurados en Program.cs.

public class ProductoServiceAPI : IProductoService
{
    private readonly HttpClient _http;

    public ProductoServiceAPI(HttpClient http)
    {
        _http = http;
    }

    // Métodos de implementación...
}
Copied!

Extensiones JSON (System.Net.Http.Json)

Antiguamente, leer un objeto desde una API era un proceso de tres pasos:

  1. client.GetAsync(...)
  2. response.Content.ReadAsStringAsync()
  3. JsonSerializer.Deserialize<T>(json)

En .NET moderno, tenemos métodos de extensión que hacen todo esto en una sola línea y de forma optimizada.

GET: Obtener datos

public async Task<List<ProductoDto>> GetProductosAsync()
{
    // Hace el GET a "https://api.luisllamas.es/v1/productos"
    // Deserializa el JSON automáticamente a List<ProductoDto>
    // Si la respuesta no es satisfactoria, lanza HttpRequestException
    return await _http.GetFromJsonAsync<List<ProductoDto>>("productos")
           ?? new List<ProductoDto>();
}
Copied!

POST: Enviar datos

public async Task CrearProductoAsync(ProductoDto nuevoProducto)
{
    // Serializa el objeto a JSON y lo envía por POST
    var respuesta = await _http.PostAsJsonAsync("productos", nuevoProducto);

    if (!respuesta.IsSuccessStatusCode)
    {
        // Manejar el error
        var error = await respuesta.Content.ReadAsStringAsync();
        throw new Exception($"Error al crear: {error}");
    }
}
Copied!

Los métodos GetFromJsonAsync, PostAsJsonAsync y PutAsJsonAsync se encuentran en el namespace System.Net.Http.Json. Asegúrate de tener el using correspondiente.

Diferencias: Server vs WebAssembly

Es importante entender que, aunque el código C# es idéntico, lo que ocurre “por debajo” es diferente:

  1. En Blazor Server: El HttpClient corre en el servidor. Puede acceder a otras APIs internas de tu red (microservicios) sin problemas de CORS.
  2. En Blazor WebAssembly: El HttpClient es solo un envoltorio sobre la API fetch del navegador.
  • Estás limitado por las reglas de seguridad del navegador (Same-Origin Policy).
  • Si tu API está en otro dominio, debes configurar CORS (Cross-Origin Resource Sharing) en el servidor de la API para permitir las peticiones.