Se suele decir que el flujo de peticiones en ASP.NET Core se basa en un pipeline de middlewares para el procesamiento de solicitudes y respuestas.
Esto significa que las solicitudes HTTP pasan a través de una serie de componentes intermedios (llamados middlewares), antes de llegar al controlador o acción que los encargado de gestionarlo.
Por ejemplo, un Middleware de autenticación puede verificar si el usuario está autenticado antes de permitir que la solicitud continúe.
De manera similar, las respuestas también pasan por estos componentes intermedios, (en orden inverso), antes de ser enviadas al cliente.
Es un mecanismo muy flexible. Cada uno de los middleware estará encargado de una tarea específica e independiente sobre la petición y respuesta.
Algunos ejemplos:
- Autenticación: Verificar la identidad del usuario.
- Enrutamiento: Determinar qué controlador o acción manejará la solicitud.
- Manejo de errores: Capturar excepciones y generar respuestas adecuadas.
- Compresión de respuestas: Reducir el tamaño de las respuestas enviadas al cliente.
- Logging: Registrar información sobre las solicitudes y respuestas.
Flujo de Middleware en ASP.NET
Los middlewares se ejecutan en un orden secuencial. Cuando una solicitud llega a la aplicación:
- Entrada: Los middlewares se ejecutan en el orden en que se registraron.
- Salida: La respuesta sigue el flujo inverso.
Ejemplo extendido
Para comprobarlo, si ejecutamos el siguiente código,
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware A: Inicio.");
await next.Invoke();
Console.WriteLine("Middleware A: Fin.");
});
app.Use(async (context, next) =>
{
Console.WriteLine("Middleware B: Inicio.");
await next.Invoke();
Console.WriteLine("Middleware B: Fin.");
});
app.Run(async context =>
{
Console.WriteLine("Middleware final ejecutado.");
await context.Response.WriteAsync("¡Hola, mundo!");
});Generaría esta salida en consola:
Middleware A: Inicio.
Middleware B: Inicio.
Middleware final ejecutado.
Middleware B: Fin.
Middleware A: Fin.Cada Middleware puede actuar sobre la solicitud o la respuesta, cuando pasa por ellos. Es decir, cada middleware puede,
- Procesar la solicitud o la respuesta (analizarla, usarla para realizar acciones, etc…)
- Modificar la solicitud o la respuesta.
- Pasar la solicitud o la respuesta al siguiente middleware.
- Cancelar la solicitud por completo.
Orden de ejecución
Dado que los middleawares se ejecutan secuancialmente, al trabajar con ellos es muy importante el orden en el que los agregamos al pipeline.
El orden influye en cómo se procesan las solicitudes y respuestas, y el comportamiento puede ser muy diferente.
Por ejemplo, el Middleware de autenticación debe estar antes del Middleware de autorización, ya que primero necesitamos saber quién es el usuario antes de verificar sus permisos.
Configuración del Middleware en ASP.NET Core
En ASP.NET, el Middleware se configura en el archivo Program.cs (o Startup.cs en versiones anteriores). Veamos un ejemplo básico de cómo configurar Middleware en una aplicación ASP.NET:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Middleware 1: Manejo de excepciones
app.UseExceptionHandler("/Home/Error");
// Middleware 2: Enrutamiento
app.UseRouting();
// Middleware 3: Autenticación
app.UseAuthentication();
// Middleware 4: Autorización
app.UseAuthorization();
// Middleware 5: Manejo de solicitudes estáticas (archivos CSS, JS, etc.)
app.UseStaticFiles();
// Middleware 6: Definición de rutas
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();En este ejemplo, hemos configurado varios componentes de Middleware en un orden específico:
UseExceptionHandler: Maneja excepciones no controladas y redirige a una página de error.UseRouting: Configura el enrutamiento de las solicitudes.UseAuthentication: Verifica la autenticación del usuario.UseAuthorization: Verifica los permisos del usuario.UseStaticFiles: Sirve archivos estáticos como CSS, JavaScript e imágenes.MapControllerRoute: Define las rutas para los controladores y acciones.
Middleware vs Controladores
Una pregunta común cuando se empieza a trabajar con ASP.NET es si para una tarea debes utilizar un controlador o un middleware.
Respuesta corta, ante la duda necesitas un controlador 😎.
Los middleware son para acciones específicas en el pipeline de solicitudes.
Respuesta larga, depende de la tarea que estés tratando de realizar:
- Middleware si necesitas actuar sobre la solicitud antes de que llegue a un controlador (por ejemplo validaciones generales, autenticación, registro y manejo de errores)
- Controlador si lo que necesitas es manejar la lógica de negocio de la aplicación entonces los controladores son la mejor opción (como la interacción con bases de datos o la ejecución de acciones específicas)