El problema
Había consumido REST APIs muchas veces como desarrollador frontend, pero nunca había diseñado el lado backend de una desde cero. Quería entender, construyéndolo yo mismo, cómo mantener la capa de acceso a datos desacoplada de la lógica de negocio, en vez de solo leer sobre el tema. Una API CRUD simple de notas era un dominio lo suficientemente chico como para enfocarme en la arquitectura y no en reglas de negocio.
Rol e impacto
- Proyecto individual, aprendizaje / fundamentos de backend.
- Aprendí a aplicar separación de responsabilidades entre controllers, services y acceso a datos.
- Aprendí el principio de inversión de dependencia (la D de SOLID) dependiendo de interfaces de repositorio en vez de implementaciones concretas.
- Aprendí y apliqué el Repository Pattern para aislar Prisma de la lógica de negocio.
Decisiones técnicas y desafíos
Si los services llaman a Prisma directamente, cada regla de negocio termina atada a un ORM específico, y testear un service implica también testear un cliente de base de datos real. Comparé llamar a Prisma directamente desde los services contra introducir una capa de repositorio entre ambos.
Elegí introducir interfaces de repositorio de las que dependen los services, con implementaciones de Prisma detrás, porque permitía que la capa de services dependiera de una abstracción en vez de una tecnología de acceso a datos concreta, siguiendo el principio de inversión de dependencia.
Habría sido más rápido poner la validación, las reglas de negocio y las llamadas a la base de datos todo en el controller. Evalué un enfoque de una sola capa contra una estructura de módulos de NestJS con controllers, services y repositorios como capas distintas.
Terminé con controllers que solo manejan aspectos de HTTP, services que contienen la lógica de negocio y repositorios que contienen el acceso a datos, porque separar esas responsabilidades hizo que cada capa fuera testeable de forma independiente y más fácil de razonar a medida que la API crecía más allá de un CRUD básico.
Stack detallado
| Capa | Tecnología | Por qué |
|---|---|---|
| Framework de API | NestJS, TypeScript | Inyección de dependencias integrada, ideal para practicar DIP |
| Base de datos | PostgreSQL, Neon | Postgres administrado para una capa de acceso a datos relacional real |
| ORM | Prisma | Queries type-safe, aisladas detrás de la capa de repositorio |
| Testing | Jest | Tests unitarios de services contra interfaces de repositorio mockeadas |
| Docs | Swagger | Documentación de API auto-generada y explorable |
