Angular y Nest, una combinación perfecta

Cómo generar una aplicación frontend y backend con 5 comando Es importante que tengas presente que este es un tutorial completo y como ya sabes al ser un tutorial completo debes ponerte cómodo, porque la lectura suele ser un poco más extensa.

· 7 min de lectura
Angular y Nest, una combinación perfecta

Ofreciendo muchas soluciones fuera de la caja para casos de uso complejos, Angular es uno de los mejores frameworks para desarrollar aplicaciones de una sola página. Otra gran cosa sobre Angular es que es muy opinable sobre la arquitectura.

Esto es especialmente importante para los equipos de desarrollo más grandes, ya que facilita la incorporación de nuevos miembros y la comunicación entre los diferentes equipos de una organización.

La CLI (interfaz de línea de comandos) de Angular es otra herramienta increíble. Nos permite andamiar toda una aplicación Angular con un solo comando y realizar tareas comunes como extender, linting, probar y construir nuestra aplicación.

NestJS, por otro lado, es un framework para desarrollar aplicaciones backend con TypeScript. Está basado en Express JS. Si nunca has oído hablar de NestJS, te recomiendo que eches un vistazo a este artículo:

Esto es lo bueno. Nest está profundamente inspirado en Angular. Ofrece soluciones listas para usar para muchos problemas, viene con los mismos bloques de construcción arquitectónicos y una interfaz de línea de comandos similar.

Esta similitud hace que sea muy fácil para los desarrolladores de Angular implementar características de backend. Puedes aplicar los mismos principios del backend al frontend.

Echemos un vistazo más de cerca aprendiendo un puñado de comandos para construir una aplicación Angular con un backend NestJS.

Lo que vamos a construir
Vamos a construir una pequeña aplicación que muestre jugadores del Real Madrid😉.

La aplicación Angular obtendrá los datos a través de REST desde un backend de Nest y los mostrará.

Para construir esta aplicación, vamos a utilizar la CLI de Nest y la CLI de Angular.

Los bloques de construcción básicos


Como se mencionó en la introducción, Angular y Nest utilizan los mismos conceptos arquitectónicos/bloques de construcción.

Módulos


Los módulos son la parte principal de toda aplicación Nest y Angular. Una aplicación pequeña puede consistir en un solo módulo, mientras que una aplicación más grande suele contener múltiples módulos.

Servicios


Los servicios son una gran manera de encapsular la lógica en una clase dedicada. Esto aumenta la encapsulación y la capacidad de prueba.

Componentes / Controlador


En Angular, hablamos de componentes, mientras que en NestJS, utilizamos Controladores. En el frontend, un componente representa un pequeño bloque en la UI. Un componente contiene una clase TypeScript, un archivo HTML, un archivo de estilos y un archivo .spec para pruebas.

En el backend, un controlador contiene métodos que entregan respuestas sobre REST.

Ambos CLIs ofrecen un gran soporte para generar esas características fuera de la caja.

Construyendo el backend


Empecemos por construir nuestra aplicación backend. Para construir una aplicación NestJS, usamos la CLI Nest que podemos instalar globalmente usando el siguiente comando.

 npm i -g @nestjs/cli

Una vez instalado, podemos utilizar la CLI para crear un nuevo proyecto NestJS. Primero vamos a crear una carpeta para nuestro proyecto y cambiar en él.

 mdkir playersapp
cd playersapp

Ahora, es el momento de crear la aplicación

nest new playersapp-backend

Una vez completado el asistente de configuración, terminamos con una aplicación NestJS. Una vez creada, podemos utilizar el script de inicio (npm start) para poner en marcha nuestro servidor. Actualmente, nuestro servidor tiene un controlador que devuelve Hello World en el puerto 3000. Ahora estamos listos para ampliar nuestra aplicación.

Añadir players endpoint


Como se mencionó anteriormente, Nest JS está profundamente inspirado en Angular. Por lo tanto, utiliza los mismos bloques de construcción. Uno de los bloques de construcción para las nuevas características es un módulo.

Un módulo es una pieza importante de la arquitectura limpia porque contiene múltiples componentes que pertenecen juntos.

nest g module players

Generamos un player's module que contendrá el controlador REST y el player's service.

La ejecución de este comando añade automáticamente el módulo recién creado imports array en el app.module.ts

Un módulo en sí mismo es bastante inútil; lo que necesitamos a continuación es un servicio que entregue a los jugadores.

nest g service players

Este comando generará players.service.ts, players.service.spec.ts y lo registrará en players.module.ts.

Hasta ahora, el players.service.ts es bastante aburrido. Es una simple clase TypeScript con una anotación.

El trabajo de este servicio es entregar una serie de jugadores. Una aplicación del mundo real como un servicio suele obtener los jugadores de una base de datos. Para nuestro pequeño ejemplo, es suficiente con añadirlos como un campo de clase pública.

import { injectable } from '@nestjs/common'; 

@injectable ()
export class playersService {
    public players = [
        {
            name: 'thibaut Curtois', 
            imgURL: https://....
            info: Texto
        },
        {
            name: 'Sergio Ramos', 
            imgURL: https://....
            info: Texto 
        }, 
        //....
    ];
}

Bien, hemos creado un módulo y un servicio que expone una serie de jugadores. Pero hasta ahora, los jugadores todavía no son accesibles a través de REST. Necesitamos un controlador.

 nest g controller players

Este comando añade un players.controller.ts, un players.controller.spec.ts y lo añade al players.modle.ts.

De nuevo, players.controller.ts es una clase TypeScript simple con la anotación @Controller. Para entregar los jugadores, podemos usar la inyección de dependencia de Nest para obtener el PlayersService y luego usarlo para acceder a los jugadores en un método con la anotación @Get

La anotación @Get indica a Nest que este método debe ser llamado si hacemos una petición GET a este controlador.

import {controller, get} from '@nestjs/common'; 
import {playersService} from './players.service';

@controller ('players')
export class playersController {
    constructor(private PlayersService: PlayerServices) {
    }
    @get()
    public players (): any {
        return this.PlayersService.players;
    }
}

Eso es todo para nuestro backend. Ahora podemos realizar una petición GET a través de la línea de comandos o Postman a localhost:3000/players Podemos abrir esta URL en un navegador para ver el array de jugadores devuelto por nuestro controlador.

¡Épico! Implementamos una API REST con 4 simples comandos:

  • nest new players-backend
  • nest g module players
  • nest g service players
  • nest g component players

Nuestro servidor está listo. Pero ya sabemos que nuestro frontend en desarrollo local será servido en un puerto diferente al del servidor. Para permitir peticiones desde un puerto diferente, necesitamos establecer las cabeceras CORS (cross-origin resource sharing) correctas. Nest JS nos permite llamar al método enableCors de nuestra app dentro del main.ts.

const app = await NestFactory.create (AppModule);
app.enableCors ();
await app.listen(3000); 

En una aplicación del mundo real no querrás permitir que todos los recursos accedan a tu backend. Por lo tanto, tu configuración CORS debe ser más sofisticada. Puedes encontrar más información en los documentos oficiales de Nest

Construyendo la aplicación Angular


Pasemos al frontend e implementemos nuestra aplicación Angular para mostrar la lista de jugadores. Al igual que Nest, también utilizaremos una interfaz de línea de comandos llamada Angular CLI para armar nuestra aplicación.

 npm i -g @angular/cli

Una vez instalado, podemos generar nuestro frontend junto al backend.

ng new players-app

Después de completar el asistente de configuración, podemos utilizar npm start o ng serve para poner en marcha nuestra aplicación Angular en localhost:4200

Al igual que el backend, crearemos un módulo de jugadores para agrupar lógicamente los servicios y componentes.

ng g module players --module=app

A diferencia del comando Nest, el comando ng g module player genera un players.module.ts pero no actualiza el app.module.ts Es necesario especificar el módulo a actualizar con la bandera --module.

De nuevo, un módulo por sí solo no hace nada. Necesitamos tener un servicio y un componente. Empecemos por generar un servicio.

ng g service players

Este comando crea un players.service.ts y un players.service.spec.ts

Usemos el HTTPClient de Angular para solicitar los jugadores desde nuestro backend.

import { Injectable } from '@angular/core';
import {HtttpClient} from '@angular/common/http';
import {observable} from 'rxjs';

@Injectable ( {
    providedIN: 'root'
})
export class PlayersService {
    constructor(private httpClient) { }
    public getPlayers(): observable<player []> {
        return this.http.get('http://localhost:3000/players');
    }
}

Nuestro PlayersService proporciona un método público getPlayers que obtiene un array de jugadores. A continuación, necesitamos un componente que llame a este método.

 ng g component players

Hemos creado con éxito un componente. La CLI nos crea automáticamente el archivo TypeScript, un archivo .spec para pruebas y un archivo HTML y de estilos según la configuración de estilos que hayas elegido durante el asistente de configuración.

Ahora podemos inyectar el PlayersService en nuestro componente y llamarlo en el hook del ciclo de vida ngOnInit para asignar los jugadores recuperados a un campo players$.

import { Componet, OnInit  } from '@angular/core'; 
import {observable} from './players.service';

@component ({
    Selector: 'app-players', 
    templateURL: './players.component.html',
    StyleUrls: ['./players.component.css']
})
export class PlayersComponent implements OnInit {
    players$: observable<any>;
    constructor (private playersService: PlayersService) {}

    ngOnInit () {
        this.players$ = this.playersService.getPlayers ();
    }
}

Para mostrar nuestros reproductores$ utilizamos Angulars async pipe en combinación con la directiva ngFor.

<div class="row">
    <div class= "players"   *ngFor="let player of players$ | async">
        <img [src]="player.imgURL" class="card-img-top" alt = "...">
        <div class="card-body">
            <h3 class="card-title">{{ player.name }}</h3>
            <p class="card-text"> {{ player. info }} </p>
        </div>
    </div>
</div>

Lo último que nos queda es implementar un componente navbar y colocar algunos estilos para la lista de nuestro reproductor.

Si ahora ejecutamos ng serve nos encontramos con la siguiente página.

¡Épico! Implementamos nuestro frontend con 4 comandos CLI y un par de líneas de código extra.

  • ng new players-frontend
  • ng g module players --module=app
  • ng g service players
  • ng g component players

Fuente

Apréndelo una vez - aplícalo en el frontend y en el backend
A lo largo de este artículo, probablemente hayas notado la similitud entre los comandos y los bloques de construcción de la arquitectura que hemos utilizado al implementar la aplicación del frontend y el backend.

Te invito a que puedas continuar leyendo más artículos como esté en el blog.

Plataforma de cursos gratis sobre programación

Artículos Relacionados

Arquitectura hexagonal con Angular
· 8 min de lectura
Primero pasos en Qwik
· 22 min de lectura
No todo es Hidratación Qwik
· 8 min de lectura