Implementation Status: The API controllers are currently stub files and not yet implemented. This documentation describes the planned architecture and patterns that will be used when the controllers are built.
The API layer (SGRH.Api) will provide the HTTP interface to the application, exposing REST endpoints that invoke application use cases. Controllers will be thin orchestrators that handle HTTP concerns while delegating business logic to the Application layer.
The application bootstraps services and middleware in Program.cs:
using Microsoft.EntityFrameworkCore;using SGRH.Persistence.Context;namespace SGRH.Api{ public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Database configuration builder.Services.AddDbContext<SGRHDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); var app = builder.Build(); // HTTPS redirection (production only) if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); } // Swagger (development only) if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseAuthorization(); app.MapControllers(); app.Run(); } }}
The current Program.cs shows basic setup. In a complete implementation, this would also call AddInfrastructure() and AddApplication() extension methods.
/// <summary>/// Get all reservations with optional filters/// </summary>[HttpGet][ProducesResponseType(typeof(PagedResult<ReservaListDto>), StatusCodes.Status200OK)]public async Task<ActionResult<PagedResult<ReservaListDto>>> GetReservas( [FromQuery] ListarReservasQuery query, CancellationToken ct){ var result = await _mediator.Send(query, ct); return Ok(result);}/// <summary>/// Get reservation by ID with full details/// </summary>[HttpGet("{id}")][ProducesResponseType(typeof(ReservaDto), StatusCodes.Status200OK)][ProducesResponseType(StatusCodes.Status404NotFound)]public async Task<ActionResult<ReservaDto>> GetReservaById(int id, CancellationToken ct){ var query = new ObtenerReservaPorIdQuery { ReservaId = id }; var result = await _mediator.Send(query, ct); if (result == null) return NotFound(new { message = $"Reserva {id} no encontrada" }); return Ok(result);}
/// <summary>/// Create a new reservation/// </summary>[HttpPost][ProducesResponseType(typeof(ReservaDto), StatusCodes.Status201Created)][ProducesResponseType(StatusCodes.Status400BadRequest)]public async Task<ActionResult<ReservaDto>> CrearReserva( [FromBody] CrearReservaCommand command, CancellationToken ct){ var result = await _mediator.Send(command, ct); return CreatedAtAction( nameof(GetReservaById), new { id = result.ReservaId }, result);}
/// <summary>/// Update an existing reservation/// </summary>[HttpPut("{id}")][ProducesResponseType(typeof(ReservaDto), StatusCodes.Status200OK)][ProducesResponseType(StatusCodes.Status404NotFound)]public async Task<ActionResult<ReservaDto>> ActualizarReserva( int id, [FromBody] ActualizarReservaCommand command, CancellationToken ct){ if (id != command.ReservaId) return BadRequest(new { message = "ID mismatch" }); var result = await _mediator.Send(command, ct); return Ok(result);}
/// <summary>/// Cancel a reservation/// </summary>[HttpDelete("{id}")][ProducesResponseType(StatusCodes.Status204NoContent)][ProducesResponseType(StatusCodes.Status404NotFound)]public async Task<IActionResult> CancelarReserva(int id, CancellationToken ct){ var command = new CancelarReservaCommand { ReservaId = id }; await _mediator.Send(command, ct); return NoContent();}