Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=c9344723-165d-405c-972e-cff4a74e6723

¿Controladores o minimal APIs para crear APIs con .NET?

Imagen ornamental. Un robot manejado como una marioneta por una mano y cuerdas. Creada con IA por campusMVP

¿Te has preguntado alguna vez si estás utilizando la mejor herramienta para crear tus APIs en .NET?

El desarrollo de APIs con .NET presenta dos enfoques principales: los Controladores (Controllers) y las APIs mínimas (más conocidas por su nombre en inglés: Minimal APIs). Ambas opciones son muy potentes y tienen ventajas y desventajas que pueden influir en la elección de uno sobre el otro dependiendo del proyecto y las necesidades específicas.

La sabiduría convencional nos ha enseñado a confiar en los controladores como la piedra angular de nuestras APIs, pero, ¿y si las minimal APIs fueran una mejor opción, al menos en muchos casos?

A continuación, detallamos algunos puntos clave sobre las dos opciones para crear APIs con .NET, para ayudarte a tomar una decisión informada.

Controladores de ASP.NET Core para crear APIs REST

Los controladores han sido la opción estándar para construir APIs en .NET durante mucho tiempo y su estructura es familiar para la mayoría de los desarrolladores de la plataforma.

Los controladores vienen equipados con funcionalidades preconstruidas como enrutamiento, vinculación de modelos o inyección de dependencias, lo que simplifica las tareas comunes. Además, el patrón MVC proporciona una clara separación de responsabilidades entre controladores, vistas y modelos, fomentando un código mantenible.

A continuación te mostramos un fragmento que muestra el código para un controlador llamado TodoItemsController, que maneja las solicitudes HTTP relacionadas con unos hipotéticos elementos de tarea (TodoItems), que es el ejemplo habitual para mostrar el funcionamiento de estas APIs con un ejemplo sencillo que no nos distraiga de lo importante:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private static readonly List<TodoItem> TodoItems = new List<TodoItem>();

        // GET: api/TodoItems
        [HttpGet]
        public ActionResult<List<TodoItem>> GetTodoItems()
        {
            return TodoItems;
        }

        // GET: api/TodoItems/5
        [HttpGet("{id}")]
        public ActionResult<TodoItem> GetTodoItem(long id)
        {
            var item = TodoItems.Find(x => x.Id == id);
            if (item == null)
            {
                return NotFound();
            }
            return item;
        }

        // POST: api/TodoItems
        [HttpPost]
        public ActionResult<TodoItem> PostTodoItem(TodoItem item)
        {
            TodoItems.Add(item);
            return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
        }

        // PUT: api/TodoItems/5
        [HttpPut("{id}")]
        public IActionResult PutTodoItem(long id, TodoItem item)
        {
            if (id != item.Id)
            {
                return BadRequest();
            }

            var index = TodoItems.FindIndex(x => x.Id == id);
            if (index == -1)
            {
                return NotFound();
            }

            TodoItems[index] = item;
            return NoContent();
        }

        // DELETE: api/TodoItems/5
        [HttpDelete("{id}")]
        public IActionResult DeleteTodoItem(long id)
        {
            var index = TodoItems.FindIndex(x => x.Id == id);
            if (index == -1)
            {
                return NotFound();
            }

            TodoItems.RemoveAt(index);
            return NoContent();
        }
    }
}

En este controlador, hemos implementado los siguientes métodos:

  • GetTodoItems(): retorna todos los elementos de tarea.
  • GetTodoItem(long id): retorna un elemento de tarea específico por su ID.
  • PostTodoItem(TodoItem item): agrega un nuevo elemento de tarea.
  • PutTodoItem(long id, TodoItem item): actualiza un elemento de tarea existente.
  • DeleteTodoItem(long id): elimina un elemento de tarea específico por su ID.

Estos métodos corresponden a las operaciones CRUD básicas y utilizan atributos HTTP para definir el comportamiento de la API, como [HttpGet], [HttpPost], [HttpPut] y [HttpDelete].

Minimal APIs de ASP.NET Core para crear APIs REST

Las Minimal APIs representan una alternativa moderna a los controladores, que se centra en una experiencia más ligera y directa. Están diseñadas para ser simples, con menos capas de abstracción, lo que puede mejorar el rendimiento, especialmente en escenarios de elevado tráfico y número de peticiones.

De hecho, podemos definir ya nuestra API directamente en program.cs sin necesidad de clases auxiliares, aunque, evidentemente, si vamos a crear una API compleja sería mejor tenerla convenientemente separada y ordenada.

Este sería el código equivalente al anterior, definido directamente en program.cs usando Minimal API (entre las líneas 4 y 47):

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

var todoItems = new List<TodoItem>();

app.MapGet("/api/todoitems", () => Results.Ok(todoItems));

app.MapGet("/api/todoitems/{id}", (long id) =>
{
    var item = todoItems.FirstOrDefault(x => x.Id == id);
    return item != null ? Results.Ok(item) : Results.NotFound();
});

app.MapPost("/api/todoitems", (TodoItem item) =>
{
    todoItems.Add(item);
    return Results.Created($"/api/todoitems/{item.Id}", item);
});

app.MapPut("/api/todoitems/{id}", (long id, TodoItem item) =>
{
    if (id != item.Id)
    {
        return Results.BadRequest();
    }

    var index = todoItems.FindIndex(x => x.Id == id);
    if (index == -1)
    {
        return Results.NotFound();
    }

    todoItems[index] = item;
    return Results.NoContent();
});

app.MapDelete("/api/todoitems/{id}", (long id) =>
{
    var index = todoItems.FindIndex(x => x.Id == id);
    if (index == -1)
    {
        return Results.NotFound();
    }

    todoItems.RemoveAt(index);
    return Results.NoContent();
});

app.Run();

En este código, se utiliza WebApplication.CreateBuilder(args) para crear la aplicación web. Luego, se utilizan métodos como MapGet, MapPost, MapPut y MapDelete para definir las rutas de la API y las operaciones CRUD correspondientes. La lógica de manejo de solicitudes se especifica directamente dentro de estos métodos.

Como puedes comprobar, es un código mucho más simple e intuitivo. Casi cualquiera es capaz de leerlo y saber qué está haciendo.

Ahora que has visto lo básico de crear la API REST con ambos métodos, vamos a resaltar las ventajas e inconvenientes de cada uno...

Ventajas de los Controladores de ASP.NET Core:

  1. Estructura Organizada: el código original sigue la estructura tradicional de un controlador de ASP.NET, lo que puede ser más familiar para desarrolladores con experiencia en ASP.NET MVC.
  2. Enrutamiento Centralizado: el enrutamiento se define a nivel de clase y método, lo que puede ser más claro y fácil de seguir, especialmente en aplicaciones con múltiples controladores y rutas complejas.
  3. Abstracción de HTTP: utiliza el concepto de ActionResult para abstraer la lógica de respuesta HTTP, lo que facilita el manejo de diferentes códigos de estado y tipos de respuesta.
  4. Separación de Responsabilidades: el controlador maneja las solicitudes HTTP y delega la lógica de negocio a métodos específicos para cada operación CRUD (GET, POST, PUT, DELETE), lo que sigue el principio de separación de responsabilidades.
  5. Funcionalidades ricas: vienen con funcionalidades incorporadas que facilitan tareas comunes.

Desventajas de los Controladores de ASP.NET Core:

  1. "Verbosidad": requiere una cantidad significativa de código para configurar y definir el controlador y sus acciones, incluso en este ejemplo tan sencillo, lo que puede aumentar la complejidad y la posibilidad de errores.
  2. Acoplamiento Fuerte: el controlador está acoplado estrechamente con ASP.NET MVC, lo que puede dificultar la reutilización de la lógica en otros contextos o frameworks.
  3. Curva de aprendizaje: puede ser desafiante para los principiantes no acostumbrados a la estructura de los controladores.

Ventajas de las Minimal APIs de ASP.NET Core:

  1. Sencillez: el código utilizando minimal APIs es más conciso y directo, lo que puede facilitar la comprensión y la mantenibilidad, especialmente para aplicaciones pequeñas o simples.
  2. Menos "fontanería": elimina la necesidad de clases de controlador y decoradores como [Route] y [ApiController], reduciendo así el código de configuración y la "verbosidad".
  3. Más ligeras y con mayor rendimiento: al no depender de clases de controlador, minimal APIs pueden reducir la sobrecarga de memoria y el tiempo de inicio de la aplicación.
  4. Simplicidad: son más fáciles de escribir y mantener que las APIs basadas en controladores.

Desventajas de las Minimal APIs de ASP.NET Core:

  1. Menos estructura organizativa: si colocas la lógica de manejo de solicitudes directamente en el punto de entrada de la aplicación, como en el ejemplo anterior (que es lo que hace mucha gente), puede ser más difícil mantener una estructura organizada, especialmente en aplicaciones más grandes o complejas.
  2. Limitaciones de flexibilidad: aunque desde .NET 8 ya pueden manejar tipos de datos complejos (no así en versiones anteriores), no permiten realizar validación de los modelos con tanta facilidad como en los controladores. No retornan ActionResult sino IResult.
  3. Negociación de contenidos: carecen de características para negociación avanzada del tipo de contenidos intercambiado, aunque se podrían implementar manualmente, pero ya las complica, claro.
  4. Lógica común: como se trata de métodos extensores, no utilizan jerarquía de clases como los controladores, por lo que dificultan la implementación de una lógica común en clases base, por ejemplo.

Documentación de APIs

Como anexo hay que mencionar una cuestión importante para cualquier API: poder documentarla con facilidad. De nada nos vale tener una API estupenda si la gente no la utiliza por falta de documentación.

En ambos casos, tanto los controladores tradicionales de ASP.NET como las minimal APIs pueden integrarse fácilmente con herramientas de documentación de API como Swagger (OpenAPI).

Estas herramientas permiten generar documentación interactiva para la API, lo que facilita que los desarrolladores entiendan cómo utilizarla correctamente, qué endpoints están disponibles y qué parámetros se esperan en cada solicitud.

Para generar documentación de API con Swagger en ASP.NET Core utilizando controladores tradicionales, se puede hacer uso de bibliotecas como Swashbuckle o NSwag. Estas bibliotecas permiten integrar Swagger en la aplicación ASP.NET Core y generar documentación automáticamente basada en los atributos [HttpGet], [HttpPost], [HttpPut], [HttpDelete], entre otros, que se aplican a los métodos de los controladores.

Para las minimal APIs, también puedes usar Swashbuckle o NSwag. Sin embargo, dado que las Minimal APIs son más simples y no utilizan atributos de acción como [HttpGet] o [HttpPost], tendrás que configurar manualmente los endpoints en la configuración de Swagger.

Las minimal APIs ofrecen compatibilidad integrada para generar información sobre los puntos de conexión de una aplicación mediante el paquete Microsoft.AspNetCore.OpenApi, que implica añadir manualmente a su definición otros métodos, mediante una interfaz fluida, que ofrecen información sobre cada método:

//...
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//...
app.MapGet("/api/todoitems", () => Results.Ok(todoItems))
	.WithName("GetTodoItems")
	.WithOpenApi();
//...

Como ves, implica añadir llamadas a esos métodos extensores, lo que las hace menos simples y directas que antes, aunque de todos modos siguen siendo más sencillas que los controladores.

La elección entre usar controladores o Minimal APIs en .NET no debería verse afectada por la elección de herramientas de documentación como Swagger. Ambas opciones pueden ser documentadas de manera efectiva con Swagger, que es una excelente herramienta para cualquier tipo de API, ya que proporciona una documentación interactiva y mantenible que facilita la comunicación y la colaboración entre desarrolladores.

Consideraciones finales

La elección entre controladores tradicionales de ASP.NET y minimal APIs, por supuesto, depende del contexto y las necesidades específicas del proyecto, y debes tener en cuenta que:

  • No es una elección binaria: es posible mezclar ambos enfoques dentro del mismo proyecto, utilizando controladores para áreas complejas y minimal APIs para funcionalidades más simples. Así que no descartes del todo nunca un método sobre el otro.
  • Complejidad del proyecto: para proyectos grandes y complejos que requieren una estructura organizativa clara y una alta abstracción de HTTP, los controladores tradicionales pueden ser la mejor opción. Por otro lado, para proyectos más pequeños o simples que priorizan la simplicidad y la agilidad en el desarrollo, las minimal APIs ofrecen seguramente la mejor opción.
  • Experiencia del equipo: si tú o tu equipo estáis cómodos con el patrón MVC, los controladores podrían ser la mejor opción. Si estáis empezando, las minimal APIs te resultarán probablemente más claras y cómodas.

En última instancia, ambas opciones tienen su lugar en el arsenal de herramientas del desarrollador de .NET, por lo que sería conveniente aprender las dos opciones con ASP.NET Core y MVC.

campusMVP campusMVP es la mejor forma de aprender a programar online y en español. En nuestros cursos solamente encontrarás contenidos propios de alta calidad (teoría+vídeos+prácticas) creados y tutelados por los principales expertos del sector. Nosotros vamos mucho más allá de una simple colección de vídeos colgados en Internet porque nuestro principal objetivo es que tú aprendas. Ver todos los posts de campusMVP
Archivado en: Desarrollo Web

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.