NestJS

Nest

Tutorial Nest: Recibir y servir imágenes

Nest multer imágenes: carga de archivos. Aprende a cargar imágenes en Nest utilizando Multer con ejemplos prácticos y detallados.

Instalación de tipos

Para subir archivos en NestJS es necesario trabajar con las clases para gestión de archivos del framework subyacente, Express o Fastify.

Ejecutar el comando:

npm i -D @types/multer

Configuración

En el archivo app.module.ts agregar la configuración de MulterModule:

import { Module } from '@nestjs/common';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { v4 as uuidv4 } from 'uuid';
import { extname } from 'path';

@Module({
  imports: [
    MulterModule.register({
      storage: diskStorage({
        // carpeta destino donde guardar los archivos
        destination: './uploads',
        // Opcional: generar un nombre único para el archivo antes de guardarlo:
        // 1f82d390-d902-4aed-ad23-d543f56f2433.png
        filename: (req, file, callback) => {
          let fileName = uuidv4() + extname(file.originalname);
          callback(null, fileName);
        }
      })
    }),
  ],
  controllers: [...],
  providers: [],
})
export class AppModule {}

Crear la carpeta uploads en el backend:

Recibir archivos en controlador

En un controlador dedicado (file.controller.ts) o un controlador de usuarios como por ejemplo user.controller.ts podemos crear un método para recibir el archivo:

    @Post('avatar')
    @UseInterceptors(FileInterceptor('file'))
    @UseGuards(AuthGuard('jwt'))
    async uploadAvatar(
        @UploadedFile() file: Express.Multer.File,
        @Request() request
    ) {
        
        if (!file) {
            throw new BadRequestException('Archivo incorrecto');
        }

        // Guardar la ruta del archivo en un atributo del user
        request.user.photoUrl = file.filename;
        return await this.userRepository.save(request.user);
    }
  • @UseInterceptors(FileInterceptor('file')) permite que el propio framework intercepte o lea el archivo que viene en el cuerpo de la petición (request) y lo guarde automáticamente siguiente la configuración MulterModule de app.module.ts
  • @UploadedFile() file: Express.Multer.File variable file, es una referencia al archivo que se ha guardado para poder saber el nombre con el que se guardó.
  • file.filename es el nombre con el que el archivo se ha guardado y que podamos usarlo para almacenarlo en base de datos, por ejemplo en un atributo como user.photoUrl.

Por último, se asocia la imagen a un usuario y se guarda el usuario en base de datos. 

Comprobar la tabla usuarios de la base de datos:

Servir el archivo guardado

Una vez el archivo ha sido subido al backend, debe poder mostrarse en el frontend.

Configurar NestJS para permitir ver los archivos de la carpeta uploads.

Configurar el acceso en el archivo app.module.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as express from 'express';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  
  // Configurar carpeta para subida imágenes/archivos
  // Ejemplo: http://localhost:3000/uploads/1f82d390-d902-4aed-ad23-d543f56f2433.png
  app.use('/uploads', express.static(join(__dirname, '..', 'uploads')));
  

  await app.listen(3000);
}
bootstrap();

Mostrar archivos en frontend

Por ejemplo en angular se podría mostrar cualquier imagen que tengamos en un atributo photoUrl de la siguiente manera en un HTML:

<img [src]="'http://localhost:3000/uploads/' + user.photoUrl" alt="Avatar">

En casos donde la imagen se usa como background se podría aplicar de la siguiente manera:

<div class="card card-cover h-100 overflow-hidden text-bg-dark rounded-4 shadow-lg"
        [style.background-image]="'url(http://localhost:3000/uploads/' + author.photoUrl + ')'">
        
        <!-- código de la card -->
</div>

A tener en cuenta, a partir de este momento las imágenes vienen de http://localhost:3000/uploads/ del backend, por tanto debe agregarse esa ruta como prefijo al nombre de las imágenes cuando se utilizan en el frontend.

En Angular, para imágenes que no vienen del backend, como por ejemplo el logo o encabezados de pantallas estáticas esas imágenes se pueden guardar en la carpeta assets y referenciarlas desde esa ruta, por ejemplo:

Y luego referenciarlo desde HTML de la siguiente manera:

    <a class="navbar-brand" routerLink="/">
      <img style="max-width:80px;" src="/assets/img/logo.svg" alt="logo">
    </a>

Verificar imágenes en frontend

En el navegador se debe comprobar que la imagen carga correctamente de la ruta NestJS uploads:

Certifícate en Nest con CertiDevs PLUS

Ejercicios de esta lección Recibir y servir imágenes

Evalúa tus conocimientos de esta lección Recibir y servir imágenes 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

  • Configuración MulterModule
  • Recibir archivos en controladores de NestJS
  • Guardar archivos en una carpeta del sistema de ficheros
  • Servir archivos al frontend