Creación de su primera Minimal API
Inicie un proyecto de Minimal API, defina controladores de rutas y devuelva resultados tipados con el mínimo código repetitivo.
Creación de su primera Minimal API es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.
¿Qué son las API mínimas?
Las API mínimas, introducidas en .NET 6, permiten crear endpoints HTTP con la mínima infraestructura: sin controladores ni atributos de acción, solo manejadores de rutas definidos directamente en Program.cs. Son ideales para microservicios y API ligeras.
La API mínima más sencilla
Una API HTTP completa en tan solo unas líneas. Los métodos MapGet, MapPost, MapPut y MapDelete definen los manejadores de rutas para cada verbo HTTP.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello, Minimal API!");
app.MapGet("/ping", () => Results.Ok(new { status = "pong" }));
app.Run();
// That's it — no Startup.cs, no controllersResultados tipados para respuestas HTTP correctas
Utilice Results o TypedResults para especificar códigos de estado HTTP y tipos de contenido correctos. Se recomienda TypedResults para inferir esquemas de OpenAPI.
app.MapGet("/products/{id}", async (int id, AppDbContext db) =>
{
var product = await db.Products.FindAsync(id);
return product is null
? Results.NotFound()
: Results.Ok(product);
});
app.MapPost("/products", async (Product product, AppDbContext db) =>
{
db.Products.Add(product);
await db.SaveChangesAsync();
return Results.Created($"/products/{product.Id}", product);
});Parámetros de ruta y cadenas de consulta
Los parámetros de ruta se capturan de la ruta URL, los parámetros de la cadena de consulta se enlazan automáticamente desde la consulta y el cuerpo de la solicitud se deserializa desde JSON.
// Route param {id} + query param ?includeDeleted
app.MapGet("/orders/{id}", async (
int id,
bool includeDeleted = false,
AppDbContext db) =>
{
var query = db.Orders.AsQueryable();
if (!includeDeleted) query = query.Where(o => !o.IsDeleted);
var order = await query.FirstOrDefaultAsync(o => o.Id == id);
return order is null ? Results.NotFound() : Results.Ok(order);
});Inyección de dependencias en manejadores de rutas
Los servicios registrados en el contenedor de DI se pueden inyectar directamente como parámetros de los manejadores de rutas. El framework los resuelve automáticamente.
builder.Services.AddScoped<ProductService>();
app.MapGet("/products", async (ProductService svc) =>
{
var products = await svc.GetAllAsync();
return Results.Ok(products);
});
app.MapDelete("/products/{id}", async (int id, ProductService svc) =>
{
var deleted = await svc.DeleteAsync(id);
return deleted ? Results.NoContent() : Results.NotFound();
});Enlace del cuerpo de la solicitud
Los parámetros que coinciden con servicios registrados se inyectan; todo lo demás se enlaza desde el cuerpo de la solicitud (JSON de forma predeterminada). Utilice [FromBody] explícitamente si es necesario.
record CreateProductRequest(string Name, decimal Price, int Stock);
app.MapPost("/products", async (
CreateProductRequest req,
ProductService svc) =>
{
var product = await svc.CreateAsync(req.Name, req.Price, req.Stock);
return TypedResults.Created($"/products/{product.Id}", product);
});Devolver códigos de estado diferentes
Results proporciona métodos de fábrica para todas las respuestas HTTP habituales. Utilícelos para crear API REST semánticamente correctas.
app.MapPut("/products/{id}", async (int id, Product update, AppDbContext db) =>
{
var existing = await db.Products.FindAsync(id);
if (existing is null) return Results.NotFound();
existing.Name = update.Name;
existing.Price = update.Price;
await db.SaveChangesAsync();
return Results.Ok(existing);
});
// Other useful Results:
// Results.BadRequest("message")
// Results.Conflict()
// Results.UnprocessableEntity(errors)
// Results.Accepted()Añadir metadatos con WithName y WithTags
Asocie metadatos a los endpoints para mejorar la documentación y el enrutamiento. Utilice WithName, WithTags y WithSummary para organizar la salida de OpenAPI.
app.MapGet("/products/{id}", GetProduct)
.WithName("GetProductById")
.WithTags("Products")
.WithSummary("Retrieves a product by its ID")
.Produces<Product>()
.Produces(404);
static async Task<IResult> GetProduct(int id, AppDbContext db)
{
var p = await db.Products.FindAsync(id);
return p is null ? Results.NotFound() : Results.Ok(p);
}Autorización en las API mínimas
Aplique RequireAuthorization() para proteger los endpoints o utilice AllowAnonymous() para excluirlos. Las directivas funcionan igual que en los controladores.
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/profile", (ClaimsPrincipal user) =>
Results.Ok(user.Identity!.Name))
.RequireAuthorization();
app.MapGet("/public", () => "No auth needed")
.AllowAnonymous();Organización con métodos estáticos
Para APIs más grandes, traslade los controladores de ruta a métodos estáticos o métodos de extensión para mantener Program.cs limpio y fácil de recorrer.
// Extension method groups endpoints by feature
public static class ProductEndpoints
{
public static void MapProductEndpoints(this WebApplication app)
{
app.MapGet("/products", GetAll);
app.MapGet("/products/{id}", GetById);
app.MapPost("/products", Create);
}
private static async Task<IResult> GetAll(AppDbContext db)
=> Results.Ok(await db.Products.AsNoTracking().ToListAsync());
// ... other handlers
}
// In Program.cs:
app.MapProductEndpoints();API Minimal completa con CRUD
Una API Minimal completa de CRUD para un recurso Todo: concisa, comprobable y lista para producción.
app.MapGet("/todos", async (AppDbContext db) =>
Results.Ok(await db.Todos.AsNoTracking().ToListAsync()));
app.MapGet("/todos/{id}", async (int id, AppDbContext db) =>
{
var todo = await db.Todos.FindAsync(id);
return todo is null ? Results.NotFound() : Results.Ok(todo);
});
app.MapPost("/todos", async (Todo todo, AppDbContext db) =>
{
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todos/{todo.Id}", todo);
});
app.MapDelete("/todos/{id}", async (int id, AppDbContext db) =>
{
int n = await db.Todos.Where(t => t.Id == id).ExecuteDeleteAsync();
return n > 0 ? Results.NoContent() : Results.NotFound();
});Comprobación rápida
¿Cómo recibe un controlador de ruta de una API Minimal un servicio de DI registrado?
Resumen: creación de su primera API Minimal
Puntos clave:
- MapGet/Post/Put/Delete definen controladores de ruta directamente en Program.cs
- Use
Results/TypedResultspara obtener los códigos de estado HTTP correctos - Los parámetros de ruta, consulta, cuerpo y DI se enlazan automáticamente
- Use
RequireAuthorization()yAllowAnonymous()para la autenticación - Organice las APIs grandes con métodos de extensión o grupos de rutas
Preguntas frecuentes
¿La lección «Creación de su primera Minimal API» es gratis?
Sí — el texto completo de «Creación de su primera Minimal API» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Creación de su primera Minimal API»?
Inicie un proyecto de Minimal API, defina controladores de rutas y devuelva resultados tipados con el mínimo código repetitivo. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C# Academy?
No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Creación de su primera Minimal API»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C# Academy?
Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Creación de su primera Minimal API
- Grupos de rutas, parámetros y validación
- Middleware y filtros en Minimal APIs
- OpenAPI, versionado y despliegue