Skip to main content

Overview

The DonaSF API is built using a classic three-tier architecture pattern that separates concerns across presentation, business logic, and data access layers. This design promotes maintainability, testability, and scalability.

Architecture Layers

API Layer

ServiciosConsolaCentralizadaRESTful API controllers handling HTTP requests and responses. Built with ASP.NET Core 10.0.

Business Logic

BussinesRulsBusiness rules, validation, and orchestration logic. Mediates between API and data layers.

Data Access

DataManagmentDatabase operations, stored procedures, and SQL Server communication.

Models

ObjectsShared data models (DTOs) and JSON objects used across all layers.

Layer Responsibilities

1. ServiciosConsolaCentralizada (API Layer)

The presentation layer exposes RESTful endpoints for client applications. Responsibilities:
  • HTTP request/response handling
  • Input validation and parameter binding
  • Authentication and authorization (JWT)
  • Status code management
  • Error formatting for clients
Key Components:
  • Controllers: AdminController, MisioneroController, DonacionController, TalonesController, etc.
  • Middleware: JWT Bearer authentication
  • Static file serving
  • Swagger/OpenAPI documentation
Example Controller Pattern:
[ApiController]
[Route("[controller]")]
public class DonacionController : Controller
{
    [HttpPost("CrearDonacion")]
    public IActionResult CrearDonacion(JSONDonacionL jSONDonacionL)
    {
        var resultados = new BDonacion().CrearDonacion(jSONDonacionL);
        if (!string.IsNullOrEmpty(resultados.error))
            return BadRequest($"Error {resultados.error}");
        // Process results...
    }
}

2. BussinesRuls (Business Logic Layer)

The business logic layer encapsulates domain rules and orchestrates data operations. Responsibilities:
  • Business rule enforcement
  • Transaction coordination
  • Data validation
  • Exception handling and error propagation
  • Cross-cutting concerns (logging, caching)
Key Classes:
  • BDonacion - Donation business logic
  • BMisionero - Missionary management
  • BAdministrador - Administrator operations
  • BTalon - Receipt (talon) processing
  • BClaveDonativo - Donation key management
Communication Pattern:
public class BDonacion
{
    public InfoCompartidaCapas CrearDonacion(JSONDonacionL jSONDonacionL)
    {
        InfoCompartidaCapas info = new InfoCompartidaCapas();
        try
        {
            IDMDonacion consulta = new CDMDonacion(new DMDonacion());
            DataTable tabla = consulta.CrearDonacion(jSONDonacionL);
            info.informacion = tabla;
            info.error = null;
        }
        catch (Exception ex)
        {
            info.informacion = null;
            info.error = ex.Message;
        }
        return info;
    }
}

3. DataManagment (Data Access Layer)

The data access layer handles all database interactions. Responsibilities:
  • SQL Server connection management
  • Stored procedure execution
  • Query construction and execution
  • Data mapping (DataTable to objects)
  • Transaction management
  • Connection pooling
Key Components:
  • ConsultasSqlServer - SQL Server query execution
  • DMDonacion - Donation data operations
  • DMMisionero - Missionary data access
  • Domain-specific data managers in DMDonaciones/ subdirectory

4. Objects (Shared Models)

The models layer contains data transfer objects (DTOs) shared across all layers. Responsibilities:
  • Data structure definitions
  • JSON serialization contracts
  • Configuration objects
  • Communication contracts between layers
Key Objects:
  • JSONDonacionL - Donation creation DTO
  • JSONMisioneroL - Missionary creation DTO
  • JSONAdministradorL - Administrator DTO
  • InfoCompartidaCapas - Inter-layer communication wrapper
  • TokenJwt - JWT token structure

Technology Stack

.NET 10

Latest .NET framework with minimal APIs and improved performance

SQL Server

Enterprise database (WSDonaciones) with stored procedures

JWT Authentication

Stateless authentication using JSON Web Tokens with bearer scheme

Twilio

SMS and communication services integration

Core NuGet Packages

<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.0.1" />
<PackageReference Include="Twilio" Version="7.13.7" />

Request Flow

Typical request flow through the architecture:

Configuration

JWT Configuration

Authentication is configured in Program.cs:
builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

Database Connection

Connection strings are managed through:
  • appsettings.json - Configuration files
  • Conecciones.cs - Connection string provider
  • ConsultasSqlServer.cs - Connection management with TrustServerCertificate=true

Design Patterns

Repository Pattern

Data access is abstracted through interfaces like IDMDonacion, allowing for testability and flexibility.

Dependency Injection

Services are registered in Program.cs and injected into controllers:
builder.Services.AddHttpContextAccessor();
builder.Services.Configure<CorreosElectronicos>(
    builder.Configuration.GetSection("CorreosElectronicos"));

Factory Pattern

Business logic classes instantiate data managers:
IDMDonacion consulta = new CDMDonacion(new DMDonacion());

Best Practices

Each layer has a single, well-defined responsibility. Controllers don’t access the database directly; business logic doesn’t handle HTTP concerns.
Errors are caught at each layer and propagated upward through the InfoCompartidaCapas.error property, allowing for appropriate handling at the API level.
Database transactions are managed in the data layer, with optional transaction support through usaTransaccionSiAplica parameters.
JWT authentication is enforced at the API layer, with secure connection strings and parameterized queries to prevent SQL injection.

Build docs developers (and LLMs) love