# Arquetipo NestJS

## ¿Que es un Arquetipo?

Si ya comenzaste a ver esta serie de artículos sabras que anteriormente explicamos que es un arquetipo o archetype en ingles, si lo hiciste puedes omitir esta introducción.

Un arquetipo es un modelo base para la creación de proyectos, aplicaciones o sistemas. En este contexto, los arquetipos ayudan a establecer una estructura inicial estándar para facilitar el desarrollo.

El arquetipo tendrá todas las librerías necesarias y bases para que se pueda reutilizar y crear aplicaciones a partir de el.

## NestJS

NestJs es un framework NodeJS progresivo para crear aplicaciones del lado del servidor eficientes, confiables y escalables.

Para mas información puedes consultar su [documentación oficial](https://nestjs.com/).

## Estructura proyecto - Arquetipo NestJS

```xml
.
├── start_app.sh           # Script con la logica para generar el arquetipo.
├── Dockerfile             # Dockerfile base que contendra el arquetipo.
├── .gitignore             # Archivos y carpetas a ignorar por Git.      
└── .dockerignore          # Archivos y carpetas a ignorar por Docker.
```

## Configuración inicial

En el archivo start\_app.sh indicaremos las instrucciones necesarias para la creacion de este arquetipo, recuerda que debe servir para diferentes equipos con lo cual las dependencias seran solamente las necesarias para que se comience a codificar un proyecto base con NestJS.

Este podria ser un ejemplo del contenido que deberia tener tu archivo `start_app.sh` :

```bash
npm i -g @nestjs/cli
nest new base-app-nestjs

cp "Dockerfile" "./base-app-nestjs"
cp ".dockerignore" "./base-app-nestjs"

cd base-app-nestjs
cd src
mkdir -p auth auth/application/services auth/application/use-cases auth/domain auth/infrastructure/adapters auth/infrastructure/controllers

npm install --save typescript @nestjs/terminus @nestjs/axios axios jest-junit
```

### Explicación

1. En la primer linea del archivo indicamos la instalacion global del cli de NestJS `@nestjs/cli`.
    
2. La segunda instrucción es para crear un proyecto base NestJS.
    
3. La tercera y cuarta instrucción realiza la copia de los archivos necesarios, en este caso el archivo `Dockerfile` y `.dockerignore`. (Puedes añadir mas archivo acorde a tus necesidades).
    
4. En las siguientes instrucciones navegamos en los directorios creados y creamos nuevos directorios que hacen referencia a la estructura de carpetas de Arquitectura Hexagonal, ejemplificado con un modulo llamado auth. (Recordá que estos directorios estan vacíos, ya que un arquetipo debe contener lo mínimo e indispensable para que los desarrolladores puedan comenzar a codificar).
    
5. Por ultimo la instrucción `npm install` en la cual indicamos las dependencias necesarias y bases que debe tener el proyecto creado a partir de nuestro arquetipo.
    

Al ejecutar este archivo `start_app.sh` deberias obtener como resultado un diretorio con la siguiente estructura:

```bash
.base-app-nestjs
├── node_modules                # Dependencias.
├── src/                        
│   ├── auth/                   # Modulo de ejemplo.
│   │  ├── application/         # Capa para orquestar la logica de negocio
│   │  │   ├── services/        # Definicion de servicios por ejemplo auth.service.ts
│   │  │   └── use-cases/       # Definicion de casos de usos por ejemplo handle-login.use-case.ts
│   │  ├── domain/              # Definicion de entidad de negocio.
│   │  ├── infrastructure/      # Capa que interactua con servicios externos
│   │  │   ├── adapters/        # Definicion de servicios externos por ejemplo firebase-auth.guard.ts
│   │  │   └── controllers/     # Definicion de controladores http. Ejemplo auth.controller.ts
│   ├── app.controller.spec.ts
│   ├── app.controller.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test/ 
├── Dockerfile                   # Dockerfile para contenerizar la aplicación.
├── .eslintrc.js                 # Configuración de ESLint
├── .gitignore                   # Archivos y carpetas a ignorar por Git
├── .dockerignore                # Archivos y carpetas a ignorar por Docker
├── nest-cli.json                # Configuración de NestJS
├── package.json                 # Dependencias y scripts del proyecto
└── tsconfig.json                # Configuración de TypeScript
```

### Dockerfile - Arquetipo

El archivo `Dockerfile` de nuestro arquetipo de NestJS contendrá las instrucciones necesarias para crear una imagen de un proyecto NestJS.

```dockerfile
#Imagen base nodejs 20
FROM node:20

# Setear directorio dentro del contenedor
WORKDIR /usr/src/app

# Copiar package.json y package-lock.json en el directorio definido
COPY package*.json ./

# Instalar dependencias
RUN npm install

# Copiar todo el contenido
COPY . .

# Builderar la aplicacion
RUN npm run build

# Exponer en puerto 3000 instruccion a modo informativo
EXPOSE 3000

# Ejecutar la aplicacion
CMD ["node", "dist/main"]
```

Para probar tu aplicación puedes hacerlo localmente ejecutando el comando `npm start` en el directorio generado a partir del archivo `start_app.sh` por defecto NestJS ejecutara la aplicación en el puerto 3000.

Puedes también probar la aplicación a partir de la imagen de Docker, en primer lugar necesitaras construir la imagen con el siguiente comando:

```bash
docker build -t project-nestjs-image .
```

En segundo lugar ejecuta la imagen construida en el paso anterior:

```bash
docker run -p 3000:3000 -t project-nestjs-image
```

## Conclusión

Tienes un arquetipo de NestJS funcional y escalable para compartirlo con diferentes equipos y que todos comiencen a codificar a partir de la base definida en el, ademas tienes configurado Docker para poder Dockerizar tu aplicación NestJS y desplegarla plataformas que soporten contenedores.
