En esta página

Proyecto final: API de catálogo de productos completa

25 min lectura TextoCap. 5 — Producción

Proyecto final: API de catálogo de productos

Este proyecto integra todos los conceptos del curso en una API funcional y bien estructurada. Implementarás:

  • Entidades relacionadas con EF Core (Producto, Categoría, Etiqueta — relación N:M)
  • DTOs inmutables con records y validación con DataAnnotations
  • Búsqueda y filtrado avanzado con LINQ (múltiples filtros encadenados, paginación)
  • Autenticación JWT con roles Admin/User
  • Middleware de logging de requests
  • Tests unitarios e de integración

Estructura del proyecto

CatalogoApi/
├── Domain/
│   ├── Entities/
│   │   ├── Producto.cs
│   │   ├── Categoria.cs
│   │   └── Etiqueta.cs
│   └── Interfaces/
│       └── IProductoRepository.cs
├── Infrastructure/
│   ├── Data/
│   │   ├── CatalogoDbContext.cs
│   │   └── Configurations/
│   │       └── ProductoConfiguration.cs
│   └── Repositories/
│       └── ProductoRepository.cs
├── Application/
│   ├── DTOs/
│   │   └── ProductoDtos.cs
│   └── Services/
│       ├── IProductoService.cs
│       └── ProductoService.cs
├── API/
│   ├── Controllers/
│   │   ├── AuthController.cs
│   │   └── ProductosController.cs
│   └── Middleware/
│       └── RequestLogMiddleware.cs
├── Tests/
│   ├── Unit/
│   │   └── ProductoServiceTests.cs
│   └── Integration/
│       └── ProductosApiTests.cs
└── Program.cs

Hitos de implementación

Hito 1: Datos y BD (30 min)

Implementa las entidades, el DbContext con Fluent API y la relación N:M entre Producto y Etiqueta usando UsingEntity. Genera la migración inicial y aplícala a SQLite:

dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet ef migrations add InitialCreate
dotnet ef database update

Hito 2: Repositorio y LINQ (30 min)

Implementa BuscarAsync con filtros encadenados, paginación y proyección a DTO. Escribe al menos 5 tests unitarios con BD InMemory para verificar los filtros.

Hito 3: Controladores y JWT (30 min)

Crea el AuthController con POST /auth/login y POST /auth/register. Protege los endpoints de creación, actualización y eliminación con [Authorize].

Hito 4: Middleware y tests de integración (20 min)

Agrega RequestLogMiddleware con tiempos de respuesta. Escribe tests de integración con WebApplicationFactory para los endpoints principales.

Funcionalidades adicionales (bonus)

Cuando completes los hitos principales, añade:

// 1. Exportar productos a CSV
[HttpGet("exportar")]
[Authorize(Roles = "Admin")]
public async Task<FileResult> ExportarCsv()
{
    var productos = await _repo.ObtenerTodosAsync();
    var csv = new StringBuilder();
    csv.AppendLine("Id,Nombre,Precio,Stock,Categoria");

    foreach (var p in productos)
        csv.AppendLine($"{p.Id},{p.Nombre},{p.Precio},{p.Stock},{p.Categoria}");

    var bytes = Encoding.UTF8.GetBytes(csv.ToString());
    return File(bytes, "text/csv", "productos.csv");
}

// 2. Endpoint de estadísticas con LINQ GroupBy
[HttpGet("estadisticas")]
public async Task<ActionResult<object>> Estadisticas()
{
    var stats = await _db.Productos
        .Where(p => p.Activo)
        .GroupBy(p => p.Categoria.Nombre)
        .Select(g => new
        {
            Categoria = g.Key,
            Total     = g.Count(),
            ValorInventario = g.Sum(p => p.Precio * p.Stock),
            PromedioStock   = g.Average(p => p.Stock),
        })
        .ToListAsync();

    return Ok(stats);
}

// 3. Búsqueda full-text con LINQ
[HttpGet("sugerencias")]
public async Task<ActionResult<IEnumerable<string>>> Sugerencias([FromQuery] string q)
{
    var nombres = await _db.Productos
        .Where(p => p.Activo && p.Nombre.Contains(q))
        .OrderBy(p => p.Nombre)
        .Take(10)
        .Select(p => p.Nombre)
        .ToListAsync();

    return Ok(nombres);
}

Checklist de entrega

Verifica que tu proyecto:

  • Compila sin errores ni advertencias (dotnet build)
  • Todas las migraciones están aplicadas
  • Los tests pasan (dotnet test)
  • Swagger documenta correctamente todos los endpoints
  • Los endpoints protegidos devuelven 401 sin token
  • La búsqueda con filtros combinados funciona
  • La paginación devuelve el total y las páginas correctas
  • El middleware registra todas las requests con tiempos

Recursos para continuar

Con estos fundamentos sólidos, los próximos pasos naturales son:

  • gRPC con .NET — para comunicación eficiente entre microservicios
  • SignalR — para comunicación en tiempo real (WebSockets)
  • Blazor — para aplicaciones web interactivas con C# en el navegador
  • MAUI — para aplicaciones móviles y de escritorio multiplataforma
  • Orleans — para sistemas distribuidos y actor model
  • Clean Architecture — para proyectos empresariales escalables

¡Felicitaciones por completar el curso de .NET con C#!

Flujo de trabajo recomendado
Empieza con las entidades y el DbContext, genera la migración y verifica el esquema en la BD. Luego implementa el repositorio con tests unitarios. Solo después crea el controlador y los tests de integración. Este flujo de abajo hacia arriba garantiza que cada capa funciona antes de construir sobre ella.
Arquitectura Clean Architecture simplificada
Para proyectos más grandes, separa en capas: Domain (entidades), Application (servicios + DTOs), Infrastructure (EF Core + repositorios), API (controladores). Esta estructura facilita los tests, el mantenimiento y la extensibilidad a largo plazo.
Nunca expongas entidades de EF Core directamente
Devuelve siempre DTOs desde tus endpoints, nunca las entidades de EF Core directamente. Las entidades tienen referencias circulares (Producto → Categoria → Productos → ...) que rompen la serialización JSON. Además, podrías exponer campos sensibles accidentalmente.