DEV Community

Leonardo Minora
Leonardo Minora

Posted on • Edited on

NestJS - Validando o envio de arquivos

Informações gerais

  • aula com FIXME para os alunos de programação orientada a serviços, do 4o ano de infoweb, do CNAT-IFRN
  • repositório de código
  • código final branch zip

objetivo

  • validar os arquivos enviados com validadores do nestjs
  • validar os arquivos enviados com validador personalizado

notas de aula

sumário

  1. pegar o código base
  2. acessar pasta do projeto e instalar bibliotecas do projeto
  3. executar a api
  4. incluir módulo nestjs para os novos endpoints
  5. codar 1 endpoint com validação nestjs para envio de imagem png
  6. codar 1 endpoint com validação nestjs para envio de imagem jpeg
  7. codar 1 endpoint com validação personalizada para envio de imagens

1. pegar o código base

pode utilizar o seu próprio código, ou baixar o zip ou fazer o clone do repositório github com o código-fonte do projeto da nota de aula anterior.

lembrando que fazendo o clone do repositório github, precisará executar na pasta do projeto o comando git checkout -b 05-upload-validacao origin/05-upload-validacao.

2. acessar pasta do projeto e instalar bibliotecas do projeto

[upload-api] $ npm install 
Enter fullscreen mode Exit fullscreen mode

3. executar a api

[upload-api] $ npm run start:dev 
Enter fullscreen mode Exit fullscreen mode

após lançar a api, o terminal deverá parecer como o console abaixo.

[14:44:53] Starting compilation in watch mode... [14:44:56] Found 0 errors. Watching for file changes. [Nest] 359207 - 20/09/2024, 14:44:57 LOG [NestFactory] Starting Nest application... [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] ConfigHostModule dependencies initialized +22ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] AppModule dependencies initialized +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] ConfigModule dependencies initialized +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] UploadModule dependencies initialized +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] ArmazenamentoModule dependencies initialized +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] ImageKitModule dependencies initialized +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [InstanceLoader] NuvemModule dependencies initialized +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RoutesResolver] AppController {/}: +32ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/, GET} route +2ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RoutesResolver] UploadController {/upload}: +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/upload/exemplo-simples, POST} route +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/upload/arquivos, POST} route +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RoutesResolver] ArmazenamentoController {/armazenamento}: +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/armazenamento, POST} route +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/armazenamento/:nome, GET} route +1ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RoutesResolver] NuvemController {/nuvem}: +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/nuvem/upload, POST} route +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/nuvem/nome/:arquivo_nome, GET} route +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [RouterExplorer] Mapped {/nuvem/id/:arquivo_id, GET} route +0ms [Nest] 359207 - 20/09/2024, 14:44:57 LOG [NestApplication] Nest application successfully started +3ms 
Enter fullscreen mode Exit fullscreen mode

4. incluir módulo nestjs para os novos endpoints

[upload-api] $ npx @nestjs/cli generate resource validacao --no-spec 
Enter fullscreen mode Exit fullscreen mode
[upload-api]$ npx @nestjs/cli generate resource validacao --no-spec ? What transport layer do you use? REST API ? Would you like to generate CRUD entry points? No CREATE src/validacao/validacao.controller.ts (234 bytes) CREATE src/validacao/validacao.module.ts (276 bytes) CREATE src/validacao/validacao.service.ts (93 bytes) UPDATE src/app.module.ts (940 bytes) 
Enter fullscreen mode Exit fullscreen mode

após adicionar o recurso/módulo, o terminal deverá parecer como o console abaixo.

[14:46:17] File change detected. Starting incremental compilation... [14:46:17] Found 0 errors. Watching for file changes. [Nest] 359539 - 20/09/2024, 14:46:18 LOG [NestFactory] Starting Nest application... [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ConfigHostModule dependencies initialized +16ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] AppModule dependencies initialized +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ValidacaoModule dependencies initialized +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] UploadModule dependencies initialized +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ArmazenamentoModule dependencies initialized +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] ImageKitModule dependencies initialized +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [InstanceLoader] NuvemModule dependencies initialized +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RoutesResolver] AppController {/}: +17ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/, GET} route +2ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RoutesResolver] UploadController {/upload}: +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/upload/exemplo-simples, POST} route +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/upload/arquivos, POST} route +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RoutesResolver] ArmazenamentoController {/armazenamento}: +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/armazenamento, POST} route +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/armazenamento/:nome, GET} route +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RoutesResolver] NuvemController {/nuvem}: +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/nuvem/upload, POST} route +1ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/nuvem/nome/:arquivo_nome, GET} route +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RouterExplorer] Mapped {/nuvem/id/:arquivo_id, GET} route +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [RoutesResolver] ValidacaoController {/validacao}: +0ms [Nest] 359539 - 20/09/2024, 14:46:18 LOG [NestApplication] Nest application successfully started +2ms 
Enter fullscreen mode Exit fullscreen mode

5. codar 1 endpoint com validação nestjs para envio de imagem png

objetivo: criar o endpoint para upload de 1 arquivo imagem png com documentação swagger.

modificar o arquivo ./src/validacao/validacao.controller.ts.

--import { Controller } from '@nestjs/common'; ++import { ++ Controller, ++ HttpStatus, ++ Post, ++ UploadedFile, ++ UseInterceptors, ++} from '@nestjs/common'; ++import { ++ ApiBadRequestResponse, ++ ApiBody, ++ ApiConsumes, ++ ApiOperation, ++ ApiResponse, ++ ApiTags, ++} from '@nestjs/swagger'; ++import { FileInterceptor } from '@nestjs/platform-express'; import { ValidacaoService } from './validacao.service';  @Controller('validacao') ++@ApiTags('validação') export class ValidacaoController {  constructor(private readonly validacaoService: ValidacaoService) {} ++ ++ @Post('upload/png') ++ @UseInterceptors(FileInterceptor('arquivo_png')) ++ @ApiConsumes('multipart/form-data') ++ @ApiBody({ ++ schema: { ++ type: 'object', ++ properties: { ++ arquivo_png: { ++ type: 'string', ++ format: 'binary', ++ }, ++ }, ++ }, ++ }) ++ @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) ++ @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) ++ @ApiBadRequestResponse({ ++ status: HttpStatus.BAD_REQUEST, ++ description: 'PROBLEMA com a imagem png enviada.', ++ }) ++ upload_png(@UploadedFile() arquivo: Express.Multer.File) { ++ return { estado: 'ok' }; ++ } }  
Enter fullscreen mode Exit fullscreen mode

após salvar o arquivo ./src/validacao/validacao.controller.ts, o terminal onde esta executando a API deve parecer com o console abaixo.
Note que foi adicionado mais um endpoint Mapped {/validacao/upload/png, POST} route

[20:19:27] File change detected. Starting incremental compilation... [20:19:27] Found 0 errors. Watching for file changes. [Nest] 415309 - 20/09/2024, 20:19:28 LOG [NestFactory] Starting Nest application... [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ConfigHostModule dependencies initialized +16ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] AppModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ConfigModule dependencies initialized +1ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] UploadModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ArmazenamentoModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ValidacaoModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] ImageKitModule dependencies initialized +1ms [Nest] 415309 - 20/09/2024, 20:19:28 LOG [InstanceLoader] NuvemModule dependencies initialized +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RoutesResolver] AppController {/}: +18ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/, GET} route +2ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RoutesResolver] UploadController {/upload}: +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/upload/exemplo-simples, POST} route +1ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/upload/arquivos, POST} route +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RoutesResolver] ArmazenamentoController {/armazenamento}: +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/armazenamento, POST} route +1ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/armazenamento/:nome, GET} route +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RoutesResolver] NuvemController {/nuvem}: +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/nuvem/upload, POST} route +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/nuvem/nome/:arquivo_nome, GET} route +1ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/nuvem/id/:arquivo_id, GET} route +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RoutesResolver] ValidacaoController {/validacao}: +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [RouterExplorer] Mapped {/validacao/upload/png, POST} route +0ms [Nest] 415309 - 20/09/2024, 20:19:29 LOG [NestApplication] Nest application successfully started +3ms 
Enter fullscreen mode Exit fullscreen mode

para essa versão do endpoint e qualquer arquivo enviado o resultado será como no console abaixo.

{ "estato": "ok" } 
Enter fullscreen mode Exit fullscreen mode

objetivo: modificar o endpoint para validar o arquivo enviado, aceitando apenas o png.

modificar o arquivo ./src/validacao/validacao.controller.ts

import {  Controller, ++ FileTypeValidator,  HttpStatus, ++ ParseFilePipe,  Post, UploadedFile, UseInterceptors, } from '@nestjs/common'; import { ValidacaoService } from './validacao.service'; import {  ApiBadRequestResponse, ApiBody, ApiConsumes, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { FileInterceptor } from '@nestjs/platform-express';  @Controller('validacao') @ApiTags('validação') export class ValidacaoController {  constructor(private readonly validacaoService: ValidacaoService) {}   @Post('upload/png') @UseInterceptors(FileInterceptor('arquivo_png')) @ApiConsumes('multipart/form-data') @ApiBody({ schema: { type: 'object', properties: { arquivo_png: { type: 'string', format: 'binary', }, }, }, }) @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) @ApiBadRequestResponse({ status: HttpStatus.BAD_REQUEST, description: 'PROBLEMA com a imagem png enviada.', }) -- upload_png(@UploadedFile() arquivo: Express.Multer.File) { ++ upload_png( ++ @UploadedFile( ++ new ParseFilePipe({ ++ validators: [new FileTypeValidator({ fileType: 'image/png' })], ++ }), ++ ) ++ arquivo: Express.Multer.File, ++ ) {  return { estado: 'ok' }; } }  
Enter fullscreen mode Exit fullscreen mode

foi adicionado no decorador (decorator) @UploadedFile, no parâmetro da assinatura do método upload_png, um novo objeto new ParseFilePipe que será responsável por executar as validações de arquivos enviados.
As validações são inseridas no atributo validators em seguida, e neste caso foi usado apenas o FileTypeValidator para verificar o tipo de arquivo (ver aviso abaixo).

Aviso by nestjs no tutorial sobre File upload com tradução pelo ChatGPT e links by me.

Para verificar o tipo de arquivo, a classe FileTypeValidator usa o tipo detectado pelo multer. Por padrão, o multer extrai o tipo do arquivo a partir da extensão do arquivo no dispositivo do usuário. No entanto, ele não verifica o conteúdo real do arquivo. Como os arquivos podem ser renomeados para extensões arbitrárias, considere usar uma implementação personalizada (como verificar o número mágico do arquivo) se seu aplicativo requer uma solução mais segura.

para esta versão com validação do endpoint, quando enviamos um arquivo imagem png, a resposta continuará a mesma acima.
caso envie qualquer outro tipo de arquivo, a resposta será como o json abaixo.

{ "message": "Validation failed (expected type is image/png)", "error": "Bad Request", "statusCode": 400 } 
Enter fullscreen mode Exit fullscreen mode

6. codar 1 endpoint com validação nestjs para envio de imagem jpeg

objetivo: criar o endpoint para upload de 1 arquivo imagem jpeg com documentação swagger.

modificar o arquivo ./src/validacao/validacao.controller.ts.

import {  Controller, FileTypeValidator, HttpStatus, ParseFilePipe, Post, UploadedFile, UseInterceptors, } from '@nestjs/common'; import { ValidacaoService } from './validacao.service'; import {  ApiBadRequestResponse, ApiBody, ApiConsumes, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { FileInterceptor } from '@nestjs/platform-express';  @Controller('validacao') @ApiTags('validação') export class ValidacaoController {  constructor(private readonly validacaoService: ValidacaoService) {}   @Post('upload/png') @UseInterceptors(FileInterceptor('arquivo_png')) @ApiConsumes('multipart/form-data') @ApiBody({ schema: { type: 'object', properties: { arquivo_png: { type: 'string', format: 'binary', }, }, }, }) @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) @ApiBadRequestResponse({ status: HttpStatus.BAD_REQUEST, description: 'PROBLEMA com a imagem png enviada.', }) upload_png( @UploadedFile( new ParseFilePipe({ validators: [new FileTypeValidator({ fileType: 'image/png' })], }), ) arquivo: Express.Multer.File, ) { return { estado: 'ok' }; } ++ ++ @Post('upload/jpeg') ++ @UseInterceptors(FileInterceptor('arquivo_jpeg')) ++ @ApiConsumes('multipart/form-data') ++ @ApiBody({ ++ schema: { ++ type: 'object', ++ properties: { ++ arquivo_jpeg: { ++ type: 'string', ++ format: 'binary', ++ }, ++ }, ++ }, ++ }) ++ @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) ++ @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) ++ @ApiBadRequestResponse({ ++ status: HttpStatus.BAD_REQUEST, ++ description: 'PROBLEMA com a imagem jpeg enviada.', ++ }) ++ upload_jpeg( ++ @UploadedFile() ++ arquivo: Express.Multer.File, ++ ) { ++ return { estado: 'ok' }; ++ } }  
Enter fullscreen mode Exit fullscreen mode

após salvar o arquivo ./src/validacao/validacao.controller.ts, o terminal onde esta executando a API deve parecer com o console abaixo.
Note que foi adicionado mais um endpoint Mapped {/validacao/upload/jpeg, POST} route

[20:59:39] File change detected. Starting incremental compilation... [20:59:39] Found 0 errors. Watching for file changes. [Nest] 418615 - 20/09/2024, 20:59:41 LOG [NestFactory] Starting Nest application... [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ConfigHostModule dependencies initialized +34ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] AppModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ConfigModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ConfigModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] UploadModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ArmazenamentoModule dependencies initialized +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ValidacaoModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] ImageKitModule dependencies initialized +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [InstanceLoader] NuvemModule dependencies initialized +2ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RoutesResolver] AppController {/}: +42ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/, GET} route +5ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RoutesResolver] UploadController {/upload}: +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/upload/exemplo-simples, POST} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/upload/arquivos, POST} route +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RoutesResolver] ArmazenamentoController {/armazenamento}: +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/armazenamento, POST} route +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/armazenamento/:nome, GET} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RoutesResolver] NuvemController {/nuvem}: +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/nuvem/upload, POST} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/nuvem/nome/:arquivo_nome, GET} route +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/nuvem/id/:arquivo_id, GET} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RoutesResolver] ValidacaoController {/validacao}: +0ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/validacao/upload/png, POST} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [RouterExplorer] Mapped {/validacao/upload/jpeg, POST} route +1ms [Nest] 418615 - 20/09/2024, 20:59:41 LOG [NestApplication] Nest application successfully started +4ms 
Enter fullscreen mode Exit fullscreen mode

para essa versão do endpoint e qualquer arquivo enviado o resultado será como no console abaixo.

{ "estato": "ok" } 
Enter fullscreen mode Exit fullscreen mode

objetivo: modificar o endpoint para validar o arquivo enviado, aceitando apenas o jpeg e jpg.

modificar o arquivo ./src/validacao/validacao.controller.ts

import {  Controller, FileTypeValidator, HttpStatus, ParseFilePipe, Post, UploadedFile, UseInterceptors, } from '@nestjs/common'; import { ValidacaoService } from './validacao.service'; import {  ApiBadRequestResponse, ApiBody, ApiConsumes, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { FileInterceptor } from '@nestjs/platform-express';  @Controller('validacao') @ApiTags('validação') export class ValidacaoController {  constructor(private readonly validacaoService: ValidacaoService) {}   @Post('upload/png') @UseInterceptors(FileInterceptor('arquivo_png')) @ApiConsumes('multipart/form-data') @ApiBody({ schema: { type: 'object', properties: { arquivo_png: { type: 'string', format: 'binary', }, }, }, }) @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) @ApiBadRequestResponse({ status: HttpStatus.BAD_REQUEST, description: 'PROBLEMA com a imagem png enviada.', }) upload_png( @UploadedFile( new ParseFilePipe({ validators: [new FileTypeValidator({ fileType: 'image/png' })], }), ) arquivo: Express.Multer.File, ) { return { estado: 'ok' }; }   @Post('upload/jpeg') @UseInterceptors(FileInterceptor('arquivo_jpeg')) @ApiConsumes('multipart/form-data') @ApiBody({ schema: { type: 'object', properties: { arquivo_jpeg: { type: 'string', format: 'binary', }, }, }, }) @ApiOperation({ summary: 'Upload de arquivo com armazenamento na nuvem' }) @ApiResponse({ status: 201, description: 'Upload de arquivo concluído.' }) @ApiBadRequestResponse({ status: HttpStatus.BAD_REQUEST, description: 'PROBLEMA com a imagem jpeg enviada.', }) upload_jpeg( -- @UploadedFile() ++ @UploadedFile( ++ new ParseFilePipe({ ++ validators: [new FileTypeValidator({ fileType: /jpeg|jpg/ })], ++ }), ++ )  arquivo: Express.Multer.File, ) { return { estado: 'ok' }; } }  
Enter fullscreen mode Exit fullscreen mode

assim como no endpoint anterior /upload/png, aqui também foi adicionado no decorador (decorator) @UploadedFile, no parâmetro da assinatura do método upload_jpeg, um novo objeto new ParseFilePipe que será responsável por executar as validações de arquivos enviados.
As validações são inseridas no atributo validators em seguida, e neste caso foi usado apenas o FileTypeValidator para verificar o tipo de arquivo.
contudo neste caso, o valor de fileType em FileTypeValidator teve uma expressão regular /jpeg|jpg/ que será processada no interpretada e validada em FileTypeValidator verifique a extensão do arquivo se é igual a jpeg ou jpg por causa do pipe adicionado.

para esta versão com validação do endpoint, quando enviamos um arquivo imagem png, a resposta continuará a mesma acima.
caso envie qualquer outro tipo de arquivo, a resposta será como o json abaixo.

{ "message": "Validation failed (expected type is /jpeg|jpg/)", "error": "Bad Request", "statusCode": 400 } 
Enter fullscreen mode Exit fullscreen mode

7. codar 1 endpoint com validação personalizada para envio de imagens

FIXME

Top comments (0)