Minimal API con C# en .NET 6
¿Qué es minimal API en .NET 6?
.NET 6 nos trae, entre muchísimas otras cosas, una forma de crear aplicaciones con poquísimas líneas de código.
A esta forma de hacer aplicaciones se le conoce como minimal API y ya viene implementado en otras tecnología desde hace tiempo.
Insisto, este concepto está disponible a partir de .NET 6, en .NET 5 no está.
¿Cuando utilizar minimal API con .NET 6?
Haremos uso de este tipo de aplicaciones cuando, por ejemplo, queramos desplegar una API con pocos endpoints.
No tienes necesidad de crear proyectos complejos con arquitectura por ejemplo MVC de ASP.
El concepto de minimal API se adapta perfectamente a los microservicios 🧐
Pasos para crear nuestra minimal API con .NET 6
Para el ejemplo que vamos a hacer en este artículo necesitamos tener instalado .NET 6, que Visual Studio 2022 ya lo tiene por defecto.
Creando el proyecto
- Abrimos Visual Studio 2022 y elegimos crear proyecto
- Elegimos el tipo de proyecto ASP.NET Core vacío
- Clic en siguiente y elegimos un nombre
- Por último, nos aseguramos en la pantalla de selección del Framework usar .NET 6.0, ya que como he dicho antes, el concepto de minimal API no está disponible en .NET 5
Analizando el proyecto creado por defecto
Si te fijas, en el proyecto creado por defecto tan sólo tenemos un fichero de clase llamado Program.cs
El contenido de dicha clase es:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
En la primera línea de código vemos una llamada al método CreateBuilder por el objeto builder para inicializar una API.
De hecho, en la línea 4 ya estamos creando un endpoint, que será el endpoint por defecto, que devuelve el texto Hello World!.
Si ejecutas el proyecto y abres en tu navegador la url de depuración verás el mensaje Hello World!
Añadiendo endpoints a Minimal API con .NET 6
Get con un parámetro en querystring
Vamos a crear un endpoint al que llamaremos saluda y le pasaremos como parámetro nuestro nombre.
El código sería:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.MapGet("/saluda", (string nombre) => $"Hola {nombre}"); app.Run();
Si corremos nuestra aplicación y llamamos al nuevo endpoint pasándole como parámetro nuestro nombre nos saludará:
http://localhost:7244/saluda?nombre=Francisco
Absurdamente fácil, no? 🤯
Este es el concepto de minimal API, crear una API con poquísimas líneas de código
Get con un parámetro como parte de la url
Si queremos enviar los parámetros como parte de la url en lugar de en un querystring sería:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.MapGet("/saluda", (string nombre) => $"Hola {nombre}"); app.MapGet("/saludaConApellido/{nombre}/{apellido}", (string nombre, string apellido) => $"Hola {nombre} {apellido}"); app.Run();
Si corremos nuestra aplicación y llamamos al nuevo endpoint pasándole como parámetro nuestro nombre nos saludará:
http://localhost:7244/saludaConApellido/Francisco/Martinez
Petición POST
El ejemplo que más rápido se me viene a la cabeza para enviar una petición POST a una API es cuando queremos autenticarnos.
Normalmente, para autenticarnos le mandamos al backend una petición POST y en el cuerpo de la petición el usuario y la contraseña.
En una Minimal API con .NET 6 quedaría así:
app.MapPost("/login", ([FromBody] UserAuthModel loginData) => { try { if(loginData == null || loginData.Email==null || loginData.Password==null) { Results.StatusCode(400); return Results.Text("Faltan los datos para la autenticación"); } var email = loginData.Email; var password = loginData.Password; // Toda tu lógica para verificar al usuario return Results.Ok(new { Token = tokenString }); } return Results.Unauthorized(); } catch(Exception e) { return Results.Problem(e.Message); } })
Devolviendo HTML
Si queremos devolver un HTML
app.MapGet("/returnhtml", () => { string html = "<h1>Ésto es un título en HTML</h1>"; html += "<p>Esto es un párrafo en HTML</p>"; return Results.Content(html, "text/html"); });
Devolviendo JSON
Si queremos devolver un JSON
app.MapGet("/return_json", () => { List<string> list = new() { "Texto 1", "Texto 2", "Texto 3", "Texto 4", }; var json = JsonSerializer.Serialize(list); return Results.Content(json, "application/json"); });
Devolviendo una respuesta asíncrona
Para el siguiente ejemplo usaremos un servicio que devuelve un JSON como respuesta.
El servicio es reqres
app.MapGet("/respuesta", async () => { HttpClient client = new(); var respuesta = await client.GetAsync("https://reqres.in/api/users?page=1"); respuesta.EnsureSuccessStatusCode(); var json = await respuesta.Content.ReadAsStringAsync(); return Results.Content(json, "application/json"); });
Si ejecutamos este nuevo endpoint veremos como hace la carga asíncrona 👇
Incluso si hacemos la solicitud con Postman, veremos como el tipo de dato que nos devuelve el endpoint es JSON
Conclusiones
Lo que te acabo de mostrar es sólo la punta del iceberg.
Con minimal API puedes usar Entity Framework, hacer inyección de dependencias... las posibilidades son casi infinitas 🚀
Hasta luego 🖖