Skip to content
raulantoPublic

About

una plantilla base para proyectos backend construida con ASP.NET Core (.NET)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Gestor de Gastos Personales Logo

ApiBase - Backend Estandarizado (.NET)

raulanto

ApiBase es una plantilla base para proyectos backend construida con ASP.NET Core (.NET) siguiendo los principios de Clean-ish Architecture (Arquitectura en Capas). Está diseñada para proveer una base sólida, escalable y segura para el desarrollo de APIs RESTful, manteniendo un estándar estricto en las respuestas HTTP, la validación de datos y el manejo de excepciones.

Resumen de Características y Tecnologías

El proyecto integra de manera coherente las siguientes tecnologías y patrones de diseño para asegurar un alto rendimiento, mantenibilidad y facilidad de prueba:

  • Framework Core: ASP.NET Core (.NET)
  • Base de Datos: PostgreSQL
  • Acceso a Datos (Micro ORM): Dapper, utilizado para ejecutar consultas SQL nativas optimizadas de alto rendimiento, evitando el overhead y la complejidad de mapeo de los ORMs tradicionales.
  • Seguridad y Autenticación: Implementación de JWT (JSON Web Tokens) con soporte integral para Access Tokens y Refresh Tokens, asegurando sesiones prolongadas de forma segura y validación de Claims.
  • Validación de Datos (Pipeline): FluentValidation, implementado para separar de forma limpia y declarativa la lógica de validación de los modelos y controladores.
  • Logging Estructurado y Monitoreo: Serilog configurado para registrar eventos tanto asíncronamente en consola como en archivos físicos con políticas de rotación diaria, facilitando la auditoría y depuración en entornos productivos.
  • Documentación Interactiva: Swagger / OpenAPI preconfigurado para documentar automáticamente los endpoints, modelos de datos, flujos de autorización y respuestas de la API.
  • Patrones de Diseño Aplicados: Inyección de Dependencias (DI), Patrón Repositorio, CQRS (Command Query Responsibility Segregation) a nivel conceptual, y un pipeline estructurado de Middlewares de ASP.NET Core.
  • Manejo Centralizado de Errores: Un Middleware global captura todas las excepciones de dominio, errores de integridad referencial de base de datos y fallas no controladas, retornando respuestas unificadas y seguras hacia el cliente.
  • Respuestas HTTP Estandarizadas: Uso de un modelo envoltorio genérico (ApiResponse<T>) que garantiza absoluta consistencia en la comunicación con las aplicaciones cliente, facilitando el desarrollo del Frontend.
  • Soporte para Paginación: Clases base y extensiones para el manejo eficiente de consultas de datos masivos.

Arquitectura del Proyecto

El proyecto está estructurado lógicamente en capas (Layered Architecture) para promover la separación de responsabilidades, facilitar las pruebas unitarias y reducir el acoplamiento:

  • Domain (Dominio): Contiene las entidades principales del negocio (ej. User, Role, Permission), enumeradores y tipos de valor. Representa el núcleo de la aplicación y es completamente agnóstico de las tecnologías o librerías externas.
  • Application (Aplicación): Contiene la lógica de negocio central, la definición de las interfaces (contratos) de servicios y repositorios, los DTOs (Data Transfer Objects) para la transferencia de información entrante/saliente, y las reglas de validación (FluentValidation).
  • Infrastructure (Infraestructura): Encargada de las implementaciones tecnológicas concretas. Aquí residen los Repositorios que utilizan Dapper para consultar PostgreSQL, los proveedores de autenticación/generación de tokens y el Middleware de excepciones.
  • Common (Transversal): Agrupa clases, utilidades, helpers y constantes transversales a toda la solución. Incluye el wrapper genérico ApiResponse<T>, modelos genéricos para paginación y la definición de las Excepciones de negocio (ConflictException, NotFoundException, ValidationException, etc.).
  • API (Presentación / Controladores): El punto de entrada HTTP de la aplicación. Define los controladores, el enrutamiento de los endpoints, las configuraciones del framework y delega la ejecución de la lógica a los servicios inyectados de la capa de Application. Esta capa no debe contener reglas de negocio.

Configuración Inicial y Ejecución

1. Requisitos Previos

  • .NET SDK (Asegúrese de instalar la versión correspondiente al framework del proyecto).
  • PostgreSQL instalado y el servicio en ejecución.
  • (Opcional) Herramienta de gestión de bases de datos como pgAdmin, DBeaver o Azure Data Studio.

2. Configuración de la Base de Datos

  1. Ubique el archivo de configuración appsettings.Development.json (o appsettings.json según el entorno) en el proyecto API.
  2. En la sección ConnectionStrings, actualice el valor de la clave DefaultConnection reemplazando los parámetros con sus credenciales locales de PostgreSQL:
    "ConnectionStrings": {
      "DefaultConnection": "Host=localhost;Port=5432;Database=ApiBaseDb;Username=tu_usuario;Password=tu_password"
    }
  3. Ejecute los scripts SQL de inicialización o migraciones correspondientes (si aplican) para generar el esquema de tablas inicial en su motor PostgreSQL.

3. Configuración de Seguridad (JWT)

En el archivo appsettings.json, es fundamental configurar la sección de JWT proporcionando una clave criptográfica de alta entropía (fuerte) para la firma y validación de los tokens:

"Jwt": {
  "Key": "tu_super_clave_secreta_muy_larga_y_segura_aqui_12345!",
  "Issuer": "ApiBaseIssuer",
  "Audience": "ApiBaseAudience",
  "DurationInMinutes": 60,
  "RefreshTokenDurationInDays": 7
}

4. Compilación y Despliegue Local

Abra una terminal en el directorio raíz del proyecto (ApiBase/) y ejecute secuencialmente los siguientes comandos del CLI de .NET:

# 1. Restaurar dependencias y paquetes NuGet de la solución
dotnet restore

# 2. Compilar la solución para verificar la integridad del código
dotnet build

# 3. Iniciar el servidor web Kestrel para desarrollo local
dotnet run

Una vez que la aplicación reporte estar escuchando peticiones, puede visualizar la documentación interactiva de la API (Swagger UI) navegando a la siguiente ruta en su navegador: https://localhost:<puerto>/swagger o utilizando http dependiendo de los perfiles de lanzamiento (launchSettings.json).


Endpoints Principales de Autenticación

A continuación, se describen los endpoints base incorporados para la gestión de acceso de usuarios y seguridad.

Registro de Nuevo Usuario

  • Método y Ruta: POST /api/auth/register
  • Cuerpo de la Petición (JSON):
    {
      "username": "johndoe",
      "email": "john@example.com",
      "password": "Password123!"
    }

Inicio de Sesión (Autenticación)

  • Método y Ruta: POST /api/auth/login
  • Cuerpo de la Petición (JSON):
    {
      "email": "john@example.com",
      "password": "Password123!"
    }
  • Resultado Esperado: Retorna el AccessToken (para el encabezado Authorization: Bearer) y el RefreshToken.

Renovación de Credenciales (Refresh Token)

  • Método y Ruta: POST /api/auth/refresh-token
  • Cuerpo de la Petición (JSON):
    {
      "token": "tu_access_token_actual_vencido",
      "refreshToken": "tu_refresh_token_valido"
    }

Cierre de Sesión (Revocación)

  • Método y Ruta: POST /api/auth/logout
  • Descripción: Invalida el Refresh Token en la base de datos de manera explícita para evitar futuros abusos.
  • Cuerpo de la Petición (JSON):
    {
      "token": "tu_access_token",
      "refreshToken": "tu_refresh_token_a_revocar"
    }

Estructura de Respuesta Estandarizada

Para simplificar y unificar el consumo de la API por parte de los desarrolladores frontend, absolutamente todos los endpoints devuelven un formato JSON predecible utilizando el modelo estructural ApiResponse<T>.

Ejemplo de respuesta de éxito (HTTP 200 OK / HTTP 201 Created):

{
  "success": true,
  "message": "Operación completada con éxito.",
  "data": {
    "id": 1,
    "username": "johndoe"
  },
  "errors": null,
  "pagination": null,
  "timestamp": "2024-01-15T12:00:00Z"
}

Ejemplo de respuesta de error de validación (HTTP 400 Bad Request / HTTP 409 Conflict):

{
  "success": false,
  "message": "Se han detectado errores en la validación de los datos.",
  "data": null,
  "errors": {
    "email": ["El formato del correo electrónico no es válido.", "El email ya se encuentra asociado a una cuenta."],
    "password": ["La contraseña debe tener una longitud mínima de 8 caracteres y contener al menos una mayúscula."]
  },
  "pagination": null,
  "timestamp": "2024-01-15T12:00:15Z"
}

Nota importante: La propiedad errors es un diccionario llave-valor (Dictionary<string, string[]>) donde la llave es el nombre del atributo o parámetro que originó el error, y el valor es el conjunto de mensajes de validación detallados.


Manejo Global y Centralizado de Excepciones

El sistema incorpora un componente de interceptación global (ErrorHandlingMiddleware.cs). Este Middleware envuelve la ejecución completa del pipeline HTTP y captura de forma unificada cualquier excepción generada (ya sea de forma intencional por reglas de negocio, o producto de un fallo inesperado del sistema o base de datos). Sus funciones principales son:

  1. Garantizar que el cliente externo nunca reciba excepciones sin procesar (Stack Traces).
  2. Transformar fallos internos en respuestas HTTP 500 bajo la misma estructura genérica estandarizada (ApiResponse<T>).
  3. Registrar la trazabilidad del error y el contexto de la solicitud en la bitácora centralizada a través de Serilog.

Lanzamiento de Excepciones de Dominio

En la lógica interna de los servicios de aplicación, no es necesario atrapar excepciones genéricas ni retornar objetos que representen el error HTTP directamente. En su lugar, se deben lanzar las excepciones fuertemente tipadas contenidas en Common.Exceptions. El Middleware detecta su tipo automáticamente y produce el código de estado HTTP (Status Code) semánticamente correcto:

// Interceptado como HTTP 404 (Not Found)
throw new NotFoundException("El recurso de usuario solicitado no fue encontrado.");

// Interceptado como HTTP 409 (Conflict) asociando explícitamente el campo con conflicto
throw new ConflictException("email", "El correo proporcionado ya está siendo utilizado por otro usuario.");

// Interceptado como HTTP 401 (Unauthorized)
throw new UnauthorizedException("Las credenciales proporcionadas no son válidas o la sesión ha expirado.");

Esta metodología asegura que los controladores y repositorios se enfoquen exclusivamente en la lógica funcional (el "Happy Path"), aislando las complejidades de presentación de errores en la infraestructura transversal y promoviendo código más limpio y fácil de mantener.

About

una plantilla base para proyectos backend construida con ASP.NET Core (.NET)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages