Controladores API en .NET con Swagger
Clase 16 de 21 • Curso de APIs con .NET
Contenido del curso
Estructura de una Web API
- 7

Configuración CORS en .NET: solución al error
07:08 min - 8

Rutas en APIs .NET con parámetros
12:50 min - 9

Documentación de APIs con OpenAPI y Swagger en .NET
14:25 min - 10

Middlewares en ASP.NET: pipeline y custom middleware
10:32 min - 11

Inyección de dependencias en .NET: ILogger
09:18 min - 12

Middleware para autenticación básica en .NET
08:17 min
Arquitectura y Middlewares
- 13

Configuración de Entity Framework Core en .NET
07:31 min - 14

Modelos C# y relaciones con Entity Framework
10:01 min - 15

Servicios con Entity Framework para ASP.NET
13:51 min - 16

Controladores API en .NET con Swagger
Viendo ahora - 17

Conectar API .NET con SQL Server
09:51 min - 18

Conectar .NET API con PostgreSQL usando Entity Framework
06:57 min - 19

Qué es Clean Architecture en .NET
09:08 min - 20

Pruebas unitarias en .NET con Copilot
09:05 min - 21

Qué sigue después de tu API con .NET
02:16 min
Crear controladores API en .NET es sencillo cuando entiendes la estructura: inyección de dependencias, rutas claras y buenas prácticas REST con códigos de estado correctos. Aquí verás cómo implementar GET y POST para usuarios y tareas, cómo usar CreatedAtAction y cómo probar todo con Swagger y una base de datos en memoria.
¿Cómo arrancar el controlador API con inyección de dependencias?
Antes de exponer endpoints, se inyecta el servicio en el controlador para aislar la lógica de acceso a datos. Así, el controlador orquesta y el servicio habla con el AppDbContext.
¿Cómo inyectar el servicio en el constructor?
- Recibe la interfaz del servicio en el constructor.
- Asigna a un campo privado con guion bajo como convención.
- Mantén el controlador delgado y sin lógica de datos.
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService; // inyección de dependencias
}
// endpoints aquí...
}
¿Qué rol cumple AppDbContext y el servicio?
- AppDbContext: persiste usuarios y tareas.
- Servicio: intermediario entre controlador y AppDbContext.
- Controlador: expone endpoints para ser consumidos por otras aplicaciones.
¿Qué endpoints GET y POST necesitas y cuál es su ruta?
Las rutas siguen la convención: api/nombre-del-controlador. Para usuarios: api/user. La diferencia entre obtener y crear no es la ruta, sino el verbo: GET para leer, POST para crear.
¿Cómo implementar get all y get by id?
- GET api/user: devuelve la lista de usuarios con await al método asíncrono del servicio.
- GET api/user/{id}: recibe un id y devuelve 404 con NotFound() si no existe.
[HttpGet]
public async Task<ActionResult> GetAll()
{
var users = await _userService.GetAllAsync();
return Ok(users); // 200 OK
}
[HttpGet("{id:int}")]
public async Task<ActionResult> GetById(int id)
{
var user = await _userService.GetByIdAsync(id);
if (user is null) return NotFound(); // 404 Not Found
return Ok(user); // 200 OK
}
- Buenas prácticas: usa nombres en plural cuando retornas colecciones (users).
- Rutas: api/user y api/user/{id} con restricción de tipo int.
¿Cómo devolver created con CreatedAtAction?
Para crear, usa POST y retorna 201 con CreatedAtAction, apuntando al método que lee por id. Así confirmas que el elemento existe y devuelves la ubicación lógica.
[HttpPost]
public async Task<ActionResult> Create([FromBody] User user)
{
var created = await _userService.CreateAsync(user);
return CreatedAtAction(
nameof(GetById), // acción de lectura
new { id = created.Id }, // ruta con id
created // cuerpo completo
); // 201 Created
}
- Razón: CreatedAtAction cumple el patrón REST para creación.
- Detalle importante: pasar el nombre del método con nameof evita errores al renombrar.
¿Cómo probar con Swagger y una base de datos en memoria?
Con Swagger, puedes ejecutar GET y POST fácilmente. Al usar una base en memoria, debes proporcionar manualmente el Id en los POST, porque no hay generación automática.
¿Cómo probar con Swagger y datos en memoria?
- Crea un usuario con POST a api/user: retorna 201 Created y el objeto creado.
- Ejecuta GET api/user: verás la lista con el usuario recién creado.
- Crea una tarea con POST a api/task: usa un userId existente, define id de la tarea, título y estado (por ejemplo, completa = false).
- Ejecuta GET api/task: devuelve la colección de tareas.
Notas prácticas: - Si la documentación de Swagger muestra un esquema incorrecto para la tarea, envía solo el userId válido y los campos de la tarea. - Asegúrate de registrar controladores: services.AddControllers() y app.MapControllers(). Ambos son necesarios para que los endpoints estén activos.
¿Qué queda pendiente para completar el CRUD?
- Implementar actualizar: método PUT o PATCH según el caso.
- Implementar eliminar: método DELETE por id.
- Mantener consistencia de códigos: 200/204 para actualización exitosa, 404 cuando no exista el recurso.
Habilidades y conceptos aplicados: - Inyección de dependencias para servicios en controladores. - Asincronía con Task y await para IO no bloqueante. - Buenas prácticas REST con Ok, NotFound y CreatedAtAction. - Diseño de rutas: api/user y api/user/{id:int}. - Pruebas con Swagger y base de datos en memoria.
¿Te quedaste con dudas o quieres compartir cómo implementaste update y delete? Deja tu comentario y cuéntanos qué retos encontraste.