Architecture Overview
The Medical Appointment Management API follows a service-oriented architecture (SOA) pattern with clear separation of concerns. This design promotes maintainability, testability, and scalability.
Architecture Layers
┌─────────────────────────────────────┐
│ HTTP Requests │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Controllers │
│ - CitaController │
│ - PacienteController │
│ - MedicoController │
│ - EspecialidadController │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Service Interfaces │
│ - ICitaService │
│ - IPacienteService │
│ - IMedicoService │
│ - IEspecialidadService │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Service Implementations │
│ - CitaService │
│ - PacienteService │
│ - MedicoService │
│ - EspecialidadService │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ In-Memory Storage │
│ List<Paciente> │
│ List<Medico> │
│ List<Especialidad> │
│ List<Cita> │
└─────────────────────────────────────┘
Layer Responsibilities
Controllers Layer
Purpose : Handle HTTP requests and responses
Receive and validate incoming HTTP requests
Parse request bodies and route parameters
Call appropriate service methods
Return properly formatted HTTP responses
Handle HTTP status codes (200, 201, 404, 400, etc.)
Controllers are kept thin - they delegate all business logic to services.
Location : Controllers/ directory
CitaController.cs
PacienteController.cs
MedicoController.cs
EspecialidadController.cs
Service Layer
Purpose : Implement business logic and data operations
Perform CRUD operations (Create, Read, Update, Delete)
Implement business rules and validation
Manage data consistency
Handle data transformations between DTOs and entities
Generate IDs for new records
Service Interfaces (Services/I*.cs):
public interface IPacienteService
{
List < Paciente > ObtenerPacientes ();
Paciente AgregarPaciente ( CreatePacienteDto paciente );
Paciente ObtenerPaciente ( int id );
void EliminarPaciente ( int id );
Paciente ActualizarPaciente ( int id , CreatePacienteDto paciente );
}
Service Implementations (Services/*Service.cs):
PacienteService.cs
MedicoService.cs
EspecialidadService.cs
CitaService.cs
Each service implementation maintains its own in-memory data store.
Models Layer
Purpose : Define data structures
Entities (Models/Entities/):
Domain models representing core business objects
Include all properties and relationships
Example: Paciente, Medico, Especialidad, Cita
DTOs (Models/Dtos/):
Data Transfer Objects for API communication
Separate creation DTOs from response DTOs
Example: CreatePacienteDto, CitaDto
Enums (Models/Enums/):
Type-safe enumerations
Example: CitaEstado (Pendiente, Confirmada, Cancelada, Completada)
Dependency Injection
The API uses ASP.NET Core’s built-in dependency injection container to manage service lifetimes and dependencies.
Service Registration
Services are registered in Program.cs:
using preliminarServicios . Services ;
using Scalar . AspNetCore ;
var builder = WebApplication . CreateBuilder ( args );
builder . Services . AddControllers ();
builder . Services . AddOpenApi ();
// Register services as singletons
builder . Services . AddSingleton < IPacienteService , PacienteService >();
builder . Services . AddSingleton < IMedicoService , MedicoService >();
builder . Services . AddSingleton < IEspecialidadService , EspecialidadService >();
builder . Services . AddSingleton < ICitaService , CitaService >();
var app = builder . Build ();
if ( app . Environment . IsDevelopment ())
{
app . MapOpenApi ();
app . MapScalarApiReference ( options =>
{
options . WithTitle ( "Mi Super API .NET 10" )
. WithTheme ( ScalarTheme . DeepSpace )
. WithDefaultHttpClient ( ScalarTarget . CSharp , ScalarClient . HttpClient );
});
}
app . UseHttpsRedirection ();
app . UseAuthorization ();
app . MapControllers ();
app . Run ();
Service Lifetimes
Singleton : Services are registered as singletons, meaning:
A single instance is created for the application lifetime
The same instance is shared across all requests
In-memory data persists for the lifetime of the application
In production, you would typically use Scoped services with a database context, creating a new instance per HTTP request.
Request Flow
A typical API request follows this flow:
HTTP Request
Client sends an HTTP request to an endpoint like POST /api/Paciente
Routing
ASP.NET Core routing directs the request to the appropriate controller action
Controller Action
Controller receives the request and validates input data
Service Call
Controller calls the appropriate service method via the interface
Business Logic
Service implementation executes business logic and data operations
Data Storage
Service updates the in-memory data store
Response
Service returns data to the controller
HTTP Response
Controller formats and returns the HTTP response to the client
Design Patterns
Repository Pattern (Implicit)
While not explicitly implemented as a separate repository layer, the service layer acts as a repository by:
Abstracting data access behind service interfaces
Encapsulating data storage implementation details
Providing a clean API for data operations
DTO Pattern
The API separates:
Create DTOs - For incoming data (e.g., CreatePacienteDto)
Entity Models - For internal representation (e.g., Paciente)
Response DTOs - For API responses (e.g., CitaDto with nested data)
This separation provides:
Control over what clients can send vs. receive
Validation at the API boundary
Flexibility to change internal models without breaking the API
Service Layer Pattern
The service layer provides:
Clear separation between HTTP concerns and business logic
Testability through interface-based design
Reusability of business logic across different controllers
Single Responsibility Principle compliance
OpenAPI Integration
The API includes full OpenAPI 3.0 specification support:
builder . Services . AddOpenApi ();
if ( app . Environment . IsDevelopment ())
{
app . MapOpenApi ();
app . MapScalarApiReference ( options =>
{
options . WithTitle ( "Mi Super API .NET 10" )
. WithTheme ( ScalarTheme . DeepSpace )
. WithDefaultHttpClient ( ScalarTarget . CSharp , ScalarClient . HttpClient );
});
}
Benefits :
Automatic API documentation generation
Interactive testing with Scalar UI
Type-safe client code generation
API contract validation
Current Limitations
In-Memory Storage : The current implementation uses in-memory lists for data storage. This means:
Data is lost when the application restarts
Not suitable for production use
No persistence layer
For production, replace with a database (SQL Server, PostgreSQL, etc.) and Entity Framework Core.
No Authentication : The API currently has no authentication or authorization. All endpoints are publicly accessible.
No Validation : The service layer currently has placeholder implementations that throw NotImplementedException. Full validation and business logic need to be implemented.
Next Steps
Data Models Explore the entity structures and relationships
Services Learn about the service layer implementation
Development Guide Learn how to extend the API
API Reference Browse all available endpoints