En el día de hoy vamos a estar usando HTTP Interceptors en Blazor. Todo lo explicado en los siguientes párrafos sirve tanto para Blazor WebAssembly, para Blazor Server y para cualquier proyecto .NET.
¿Qué son los Interceptors?
Un interceptor permite que puedas inspeccionar y/o modificar todas las solicitudes HTTP de un HttpClient. Esto significa que antes de realizar cualquier llamado al servidor, podes editar su contenido y también la respuesta.
Dicho de un modo bruto, podemos decir que tenemos un middleware del lado del cliente.
¿Cómo se lo puede usar?
Sea con Blazor o JS, los interceptors se los suelen usar para lo mismo:
- Imprimir en la consola cada solicitud HTTP que se realiza.
- Capturar todas respuestas con código 500 con fines de monitoreo.
- Agregar a las solicitudes el encabezado Authorization junto con su token.
- Implementar una lógica de reintentos.
- Mostrar un componente UI de “Cargando…” cada vez que se realiza una petición.
Y la lista puede tener muchas opciones más.
Creando Interceptors de Blazor
En este ejemplo voy a mostrar un caso sencillo donde vamos a crear un interceptor que muestre en la consola del navegador todos los códigos de estado de todas las respuesta que recibamos del servidor.
- Primero vamos a necesitar crear una clase que herede de DelegatingHandler.
- Segundo, simplemente sobrescribimos el método SendAsync.
- Por último agregamos en ese método la implementación de código que sea necesaria.
Y nos quedaría algo similar a la siguiente clase.
[FALTA EL GITHUB GIST]
public class StatusCodeHttpMessageHandler : DelegatingHandler
{
private readonly ILogger<StatusCodeHttpMessageHandler> _logger;
public StatusCodeHttpMessageHandler(ILogger<StatusCodeHttpMessageHandler> logger)
{
_logger = logger;
InnerHandler = new HttpClientHandler();
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Antes de enviar la solicitud
Console.WriteLine("Antes de enviar la solicitud al servidor...");
// Puedes realizar alguna lógica personalizada aquí
// por ejemplo, agregar encabezados adicionales a la solicitud
// Llama al siguiente delegado en la cadena
var response = await base.SendAsync(request, cancellationToken);
_logger.LogInformation($"{(int)response.StatusCode} - {response.StatusCode}");
// Después de recibir la respuesta
Console.WriteLine("Después de recibir la respuesta del servidor...");
// Puedes realizar alguna lógica personalizada aquí
// por ejemplo, leer o modificar la respuesta antes de devolverla
return response;
}
}
Agregando nuestro Interceptor al HttpClient
Cuando iniciamos un proyecto de Blazor, nos encontramos con que en la clase Program se crea una nueva instancia de HttpClient y esta instancia se agrega como Scoped en el contenedor de inyección de dependencias de .NET Core.
Lo que vamos a hacer nosotros es modificar esto para poder pasarle al constructor del HttpClient nuestro nuevo interceptor.
builder.Services.AddScoped<StatusCodeHttpMessageHandler>();
builder.Services.AddScoped(sp =>
{
var handler = sp.GetRequiredService<StatusCodeHttpMessageHandler>();
return new HttpClient(handler)
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
};
});
De esta manera cada vez que se inyecte el HttpClient en algún componente se lo utilice para realizar solicitudes al servidor, estas van a pasar por nuestro interceptor sin falta.
Conclusión
Los interceptors son muy usados en el desarrollo web y no pueden faltar en Blazor.
Les dejó el este mismo código en un repositorio de GitHub para que puedan clonarlo y probarlo ustedes mismos.
Si encuentras útil este trabajo y deseas mostrar tu apoyo, siempre puedes invitarme a un buen café ☕.