REST API for managing tours, reservations, and payments — built with ASP.NET Core 9 and dockerized with SQL Server.
📄 Read this in: English | Español
Academic Project — 2025 Universidad Privada Domingo Savio — Ing. de Sistemas Course: Web Application Development / Web Services
REST API that manages the complete lifecycle of a tourism system: tour management, user registration, reservations with capacity control, additional reservation details, and payments.
Key features:
- Full CRUD for 5 resources: tours, users, reservations, reservation details, and payments
- Logical delete (
IsActive) and physical delete on all resources, with reactivation support - Capacity validation when creating or updating reservations
- Password hashing with HMACSHA512 + salt
- Automatic database migration and seed data on startup
- CORS configured for development environments
| Category | Technology | Version |
|---|---|---|
| Framework | ASP.NET Core | 9.0 |
| ORM | Entity Framework Core | 9.0.6 |
| Database | SQL Server | 2022 |
| API Docs | OpenAPI (Swagger) | 9.0.5 |
| Containers | Docker + Docker Compose | — |
MicroServicioTurismo/
├── Controllers/ # HTTP endpoints (5 controllers)
├── DTOs/ # Data transfer objects
├── Models/ # Domain entities
├── Data/
│ ├── AppDbContext.cs # EF Core context
│ └── DbInitializer.cs # Test data seed
├── Utils/
│ └── PasswordHelper.cs # HMACSHA512 hashing with salt
├── dockerfile
└── docker-compose.yml
Data model:
User ──────< Reservation >────── Tour
│
┌───────┴────────┐
ReservationDetail Payment
The docker-compose.yml spins up two services on an internal backend network:
| Service | Image | Port |
|---|---|---|
db |
SQL Server 2022 | 1433 |
api |
ASP.NET Core 9 (local build) | 8001 → 8080 |
cd MicroServicioTurismo
docker compose up --buildThe API will be available at http://localhost:8001/api/.
The connection string is injected as an environment variable from the compose file — no changes to
appsettings.jsonrequired.
-
Clone the repository:
git clone <repository-url> cd MicroServicioTurismo
-
Configure the connection string in
appsettings.json:{ "ConnectionStrings": { "DefaultConnection": "Server=<host>;Database=TurismoDB;User=sa;Password=<password>;Encrypt=False;" } } -
Run:
dotnet run
The application automatically applies migrations and inserts seed data on startup.
All controllers follow the api/[controller] pattern and expose the same set of operations:
| Method | Route | Description |
|---|---|---|
GET |
/api/{resource} |
List active records |
GET |
/api/{resource}/active |
List active (explicit) |
GET |
/api/{resource}/inactive |
List inactive |
GET |
/api/{resource}/{id} |
Get by ID |
POST |
/api/{resource} |
Create |
PUT |
/api/{resource}/{id} |
Update |
DELETE |
/api/{resource}/{id} |
Logical delete |
PATCH |
/api/{resource}/{id}/reactivate |
Reactivate |
DELETE |
/api/{resource}/{id}/physical |
Permanent delete |
Resources: tours · users · reservations · reservationdetails · payments
Business rules:
- Reservation: validates that user and tour are active, and checks seat availability before confirming.
- User: enforces unique
usernameandemailon creation.
On first startup with an empty database, DbInitializer inserts:
| Entity | Records |
|---|---|
| Users | 3 (2 Customer, 1 Employee) — default password: Prueba123 |
| Tours | 2 (city tour and mountain hike) |
| Reservations | 2 (Confirmed and Pending) |
| Details | 2 (bilingual guide, optional lunch) |
| Payments | 2 (Method: Card, Status: Completed) |
Developed individually as an academic project.
