Blog

Cómo crear una aplicación Full-Stack con React, NestJS y Nx

🏁 TL;DR

Nx es un conjunto de herramientas que nos permiten construir aplicaciones full-stack de una manera más sencilla por medio de mono repositorios reforzando además las buenas prácticas de programación. Podemos generar aplicaciones full-stack con NestJS y React por medio de la ejecución de algunos sencillos comandos.


Pre requisitos:

  • ⚛️ Conceptos básicos de React.
  • 🐈 Conocimiento básico de NestJS.

😮 ¿Por qué utilizar mono repos?

Las organizaciones por lo general trabajan y dan mantenimiento a múltiples proyectos y no siempre es sencillo mantener estándares o reutilizar código entre ellas.

Implementar una estrategia de mono repositorio nos va a permitir centralizar el código de nuestras diferentes aplicaciones un único repositorio permitiendo así compartir código entre nuestras aplicaciones.

Entre las ventajas que nos ofrece esa estrategia podemos recalcar:

  • Facilidad para compartir código entre aplicaciones.
  • Un mejor manejo de dependencias a lo largo de distintos proyectos así como la compatibilidad de sus versiones.
  • Permite mayor fluidez en el trabajo entre distintos equipos.

Existen herramientas que nos permiten abstraer nuestro código en librerías e implementar mono repos como los paquetes privados de npm, Lerna o Yarn Workspaces, sin embargo existen varios aspectos dónde podríamos vernos beneficiados con mejores herramientas.

Con Nx tenemos a nuestro alcance una colección de herramientas que nos permitirán administrar nuestro mono repo de una mejor manera gracias Nx CLI: una herramienta de línea de comandos basada en Angular Schematics con la cuál podremos generar código de manera consistente con solo ejecutar una serie de comandos. Nx además provee herramientas para optimizar nuestro proceso de pruebas automatizadas y despligue.

🙌🏽 Aplicaciones full-stack utilizando Nx

Otro uso que podemos dar a los mono repositorios son las aplicaciones full-stack. Nx resulta poderosamente conveniente cuando hablamos específicamente de aplicaciones full-stack con TypeScript ya que nos permite mantener el código del front end y el back end en un mismo repositorio junto con librerías que facilitan la reutilización de código cómo interfaces y funciones utilitarias.

Para este ejemplo vamos a utilizar NestJS, un framework dogmático de NodeJS que busca ser robusto y escalable por medio de la implementación de buenas prácticas y patrones de diseño. Esta fuertemente inspirado en la arquitectura de Angular. NestJS ha ganado bastante popularidad gracias a sus características.

Es muy común ver implementaciones full-stack con Angular y NestJS debido a que comparten muchas características e implementan patrones similares, sin embargo es completamente posible utilizar React con TypeScript.

Nx ofrece una serie de comandos para generar estructuras de aplicaciones full-stack, entre ellas podemos generar Angular + NestJS, o React + NodeJS con Express. De momento no existe una opción directa para combinar estas opciones sin embargo podemos hacerlo manualmente y así poder aprovechar el potencial tanto de NestJS en el backend como la flexibilidad y rapidez de desarrollo de React en el front end.

⚙️ Configurando una aplicación React + NestJS

Aplicación front end con React y TypeScript

El primer paso que vamos a seguir es la creación de un espacio de trabajo junto con la aplicación de React. Para esto vamos a ejecutar el siguiente comando:

npx create-nx-workspace@latest

Una vez hecho esto vamos a elegir un nombre para nuestra organización. La organización va a contener los distintos proyectos entre los cuales queramos compartir código.

Después de esto vamos a seleccionar la opción ”a workspace with a single React application

Nx va a generar por nosotros toda la estructura del espacio de trabajo junto con una aplicación React funcional.

Podemos ejecutar la aplicación con el siguiente comando

npx nx serve <nombre_de_la_aplicacion>

API con NestJS

Seguidamente vamos a generar nuestro api NestJS.

Si ejecutamos el comando nx list podremos observar las distintas opciones que nos ofrece Nx para generar código.

Vamos a ejecutar yarn add --dev @nrwl/nest para añadir la capacidad de generar aplicaciones NestJS.

Después de esto vamos a ejecutar el comando:

npx nx g @nrwl/nest:app api --frontendProject=<nombre_de_la_aplicacion_front_end>

Con este comando ya podremos ver nuestro espacio de trabajo conteniendo el código de un api NestJS.

Además de esto tenemos una configuración de proxy creada automáticamente.

{
  "/api": {
    "target": "http://localhost:3333",
    "secure": false
  }
}

En este punto ya tenemos el front end y el back end. En el siguiente paso vamos a compartir código entre ambas aplicaciones.

🤝 Compartir código entre distintas aplicaciones

Una de las ventajas de utilizar librerías de Nx para compartir código es que no necesitaremos procesos extra de despliegue como es el caso de los paquetes privados de NPM donde primero necesitamos desplegar el paquete y luego actualizar la versión en nuestra aplicación. Con Nx es tan sencillo como crear un nuevo pull request.

Para generar una librería que podamos acceder desde los distintos proyectos vamos a ejecutar el siguiente comando.

npx nx g @nrwl/workspace:lib data

Nx va a generar el código de nuestra librería, en la ruta libs/data/src/lib podremos encontrar un archivo de TypeScript que eventualmente podremos importar en nuestras aplicaciones. Para probar podemos escribir un tipo de dato que vayamos a utilizar tanto en el front end como en el back end, esto nos permitirá evitar duplicar el código de nuestras interfaces de TypeScript.

export interface Book {
  title: string;
  author: string;
  isbn: string;
  cover: string;
}

Seguidamente vamos a actualizar un poco el código para poder probar la aplicación:

  1. En el API, vamos a actualizar el app.service.ts importando el nuevo tipo de dato por medio de la línea: import { Book } from '@public-library/data';
import { Injectable } from "@nestjs/common"
import { Book } from "@public-library/data"

@Injectable()
export class AppService {
  books: Book[] = [
    {
      title: "Clean Code",
      author: "Robert C. Martin",
      isbn: "9780132350884",
    },
    {
      title: "The Pragmatic Programmer",
      author: "Andy Hunt & Dave Thomas",
      isbn: "9780132119177",
    },
    {
      title: "Working Effectively with Legacy Code",
      author: "Michael C. Feathers",
      isbn: "9780131177055",
    },
  ]

  getData(): Book[] {
    return this.books
  }
}

Si estamos utilizando VS Code, es importante tomar en cuenta que cada vez que agregamos una nueva librería debemos reiniciar el servidor de TypeScript ya sea reiniciando el editor o ejecutando Cmd + Shift + P y ejecutando el comando TypeScript: Restart TS Server.

  1. Vamos a crear una ruta personalizada en el controlador para poder manipular la petición al del front end al API
import { Controller, Get } from '@nestjs/common';

import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('books')
  getData() {
    return this.appService.getData();
  }
}
  1. En la aplicación de React vamos a modificar el archivo app.tsx para poder obtener los datos del API y listarlos de la siguiente manera. Al igual que en el API vamos a importar nuestra librería con exactamente la misma interfaz.
import React, { useEffect, useState } from 'react';
import { Book } from '@public-library/data';

export const App = () => {

  const [books, setBooks] = useState<Book[]>([]);

  useEffect(() => {
    fetch('/api/books')
      .then((_) => _.json())
      .then(setBooks);
  }, []);

  return (
    <>
     <h1>Books</h1>
      <ul>
        {books.map((t) => (
          <li key={t.isbn} className={'book'}>{t.title}</li>
        ))}
      </ul>
    </>
  );
};

export default App;

¡Y listo! una vez finalizado este paso tendremos una estructura escalable lista para empezar a desarrollar nuestra aplicación full-stack TypeScript con React y NestJS.

🎯 Conclusion

El uso de mono repos nos permite administrar nuestro código de una mejor manera tanto para agrupar y compartir código entre distintas aplicaciones de una organización así como para nuestras aplicaciones full-stack.

Nx ofrece una serie de herramientas y buenas prácticas que facilitarán mucho la implementación de una estrategia de mono repos y de aplicaciones full-stack escritas en TypeScript.

A pesar de que Nx no ofrece por defecto la opción de generar una aplicación full-stack combinando NestJs y React, es posible hacerlo manualmente mediante una serie de comandos.

Fuentes y Documentación adicional

¿Utilizarías React con NestJS, tienes experiencia utilizando estas tecnologías juntas?

Espero sus comentarios.

¡Hasta la próxima! 😁

Foto por Iva Rajović on Unsplash