NestJS

Nest

Tutorial Nest: Desarrollo e inyección de servicios

Nest servicios: creación y ejemplos. Domina la creación y uso de servicios en Nest con ejemplos prácticos y detallados.

La inyección de servicios es una técnica que permite a una clase obtener las dependencias que necesita desde fuentes externas en lugar de crearlas por sí misma.

NestJS, al ser un framework para la creación de aplicaciones de servidor con Node.js, hace un uso intensivo de este patrón, particularmente a través de su sistema de módulos y proveedores.

¿Qué es un servicio?

Un servicio es una clase que se utiliza para organizar la lógica de negocio de una aplicación.

Los servicios se utilizan para llevar a cabo tareas específicas, como interactuar con bases de datos, realizar llamadas a APIs externas, realizar cálculos complejos o cualquier otra tarea que no deba realizarse directamente en los controladores.

Los servicios se pueden inyectar en controladores, otros servicios o cualquier componente que necesite utilizar su funcionalidad.

Ejemplo de un servicio simple:

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

@Injectable()
export class AppService {
  getHello(): string {
    return '¡Hola Mundo!';
  }
}

¿Qué significa @Injectable?

La anotación @Injectable() es un decorador proporcionado por NestJS. Indica que la clase puede ser administrada por el sistema de inyección de dependencias de NestJS.

En otras palabras, una vez que una clase tiene este decorador, puede ser inyectada como dependencia en otro componente.

Inyectando un servicio

Para inyectar un servicio, simplemente se debe declarar en el constructor del componente en el que se desee utilizar. NestJS se encargará automáticamente de instanciar y proporcionar el servicio.

Ejemplo:

Suponiendo que se tiene el servicio AppService del ejemplo anterior y se desea inyectar en un controlador:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

En el código anterior, AppService es inyectado en AppController a través del constructor. Ahora, el método getHello() del servicio está disponible para ser utilizado en el controlador.

Proveedores

Los proveedores son componentes fundamentales en NestJS que encapsulan y proporcionan funcionalidades o servicios a otras partes de la aplicación.

Los servicios son un tipo específico de proveedor que se utiliza comúnmente para manejar la lógica de negocio y acceder a datos.

Los proveedores y servicios se pueden inyectar en otros componentes, como controladores y otros proveedores, mediante la inyección de dependencias.

Un proveedor puede ser cualquier valor, clase, servicio o función que se desea que esté disponible para ser inyectado en otros componentes.

Beneficios de la inyección de dependencias

  • Desacoplamiento: Los componentes no necesitan conocer detalles específicos sobre cómo se crean sus dependencias.
  • Reutilización: Los servicios se pueden reutilizar en diferentes partes de la aplicación.
  • Testabilidad: Facilita la escritura de pruebas unitarias, ya que las dependencias pueden ser fácilmente simuladas o reemplazadas.

Registro de proveedores

Para que un servicio pueda ser inyectado, primero debe ser registrado como proveedor en un módulo. NestJS utiliza módulos para organizar partes relacionadas de la aplicación.

Cuando se registra un servicio como proveedor, este se hace disponible para ser inyectado en cualquier componente que pertenezca al mismo módulo o en módulos que importen el módulo en el que se encuentra registrado.

Ejemplo de registro de AppService en un módulo:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

En el fragmento anterior, AppService se registra como proveedor en AppModule. Esto significa que cualquier componente dentro de AppModule puede tener AppService inyectado a través de su constructor.

Exportación de servicios

En algunos casos, se puede necesitar que un servicio esté disponible para ser inyectado en otros módulos. Para esto, se puede utilizar la propiedad exports del decorador @Module().

Por ejemplo, supongamos que en un módulo llamado MiModulo se busca que el servicio MiServicio sea accesible tanto dentro como fuera de MiModulo, el código podría verse de la siguiente manera:

import { Module } from '@nestjs/common';
import { MiServicio } from './mi-servicio';

@Module({
  providers: [MiServicio], // Registra el servicio en providers
  exports: [MiServicio], // Registra el servicio en exports
})
export class MiModulo {}

Inyección de dependencias personalizadas

NestJS ofrece la capacidad de definir proveedores personalizados, lo que permite mayor control sobre cómo se resuelven las dependencias.

Por ejemplo, supongamos que se quiere inyectar una configuración o un valor específico:

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: () => {
    return createConnection({ /* opciones */ });
  },
};

@Module({
  providers: [connectionFactory],
})
export class DatabaseModule {}

En este caso, se está creando un proveedor personalizado utilizando la clave 'CONNECTION'. El método useFactory define cómo se debe crear esta conexión. Cualquier componente que necesite esta conexión simplemente tendría que inyectar 'CONNECTION'.

Ámbito de proveedores

Por defecto, los proveedores en NestJS son singleton, es decir, se crea una única instancia que es compartida entre todos los consumidores. Sin embargo, en algunos casos se podría necesitar que cada consumidor reciba una nueva instancia del proveedor.

NestJS ofrece diferentes ámbitos para los proveedores: DEFAULT (singleton), REQUEST (nueva instancia por cada petición HTTP) y TRANSIENT (nueva instancia cada vez que se solicita).

Ejemplo de un proveedor transitorio:

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TransientService {}

Conclusión

La inyección de servicios es fundamental en NestJS. Permite una arquitectura desacoplada y modular, facilitando pruebas, mantenimiento y escalabilidad. Al entender cómo funciona este mecanismo, se tiene una base sólida para construir aplicaciones robustas y eficientes en NestJS.

Certifícate en Nest con CertiDevs PLUS

Ejercicios de esta lección Desarrollo e inyección de servicios

Evalúa tus conocimientos de esta lección Desarrollo e inyección de servicios con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Nest

Accede a todas las lecciones de Nest y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Certificados de superación de Nest

Supera todos los ejercicios de programación del curso de Nest y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender el concepto de servicio en NestJS.
  2. Saber qué significa el decorador @Injectable.
  3. Conocer cómo inyectar un servicio.
  4. Diferenciar entre servicios y proveedores.
  5. Entender los beneficios de la inyección de dependencias en NestJS.