· Diogo Felizardo · NestJS  · 5 min de leitura

Upload de Arquivos Públicos para Amazon S3 com NestJS

Aprenda a integrar o Amazon S3 com NestJS para realizar uploads de arquivos públicos, com um guia passo a passo e exemplos de código.

Aprenda a integrar o Amazon S3 com NestJS para realizar uploads de arquivos públicos, com um guia passo a passo e exemplos de código.

Sumário

  1. Introdução
  2. Configurando o Projeto NestJS
  3. Instalando Dependências
  4. Configurando o Amazon S3
  5. Criando o Serviço de Upload
  6. Criando o Controller de Upload
  7. Testando o Upload de Arquivos
  8. Considerações Finais
  9. Repositório no GitHub

Introdução

No desenvolvimento de aplicações web modernas, o armazenamento de arquivos é uma funcionalidade essencial. O Amazon S3 (Simple Storage Service) é uma solução escalável e confiável para armazenar e recuperar qualquer quantidade de dados a qualquer momento. Neste post, vamos explorar como integrar o Amazon S3 em uma aplicação NestJS para realizar o upload de arquivos públicos.

Configurando o Projeto NestJS

Primeiramente, vamos criar um novo projeto NestJS. Se você já possui um projeto, pode pular para a próxima seção.

# Instale o CLI do NestJS globalmente, se ainda não tiver
npm install -g @nestjs/cli

# Crie um novo projeto
nest new upload-s3

Navegue até o diretório do projeto:

cd upload-s3

Aqui coloca uma imagem do terminal mostrando a criação do projeto.

Instalando Dependências

Para interagir com o Amazon S3, precisamos instalar o AWS SDK e algumas outras dependências úteis.

npm install aws-sdk multer multer-s3 @nestjs/config
  • aws-sdk: Biblioteca oficial da AWS para interagir com os serviços da AWS.
  • multer: Middleware para lidar com multipart/form-data, usado para uploads de arquivos.
  • multer-s3: Integração do Multer com o S3.
  • @nestjs/config: Módulo para gerenciar variáveis de ambiente no NestJS.

Configurando o Amazon S3

Antes de configurar o código, você precisa criar um bucket no Amazon S3 e obter as credenciais de acesso.

  1. Criar um Bucket no S3

    • Acesse o console do Amazon S3.

    • Clique em “Criar bucket”. Criar bucket

    • Dê um nome único ao bucket. Nome único

    • Configure as permissões de acordo com sua necessidade (para arquivos públicos, certifique-se de configurar as permissões públicas). Configurar permissões

    • Para saber qual em qual região esta seu bucket, basta clicar no menu ao lado do seu usuário, nesse caso é o us-east-2 salve essa informação. Configurar permissões

  2. Obter Credenciais de Acesso

    • Acesse o IAM Management Console.
    • Crie um novo usuário. Criar usuário
    • Dê um nome para seu usuário. Nome do usuário
    • Busque e marque a política de permissão AmazonS3FullAccess, clique em próximo e depois Criar usuário Política de Permissão
    • Com o usuário criado, clique em cima do mesmo e depois clique na aba de Credenciais de Segurança, logo em seguida escolha a opção Criar chave de acesso. Selecione o usuário
    • No caso de uso, marque a opção Código local e va para o próximo passo. Selecione o usuário
    • Defina uma etiqueta (opcional). Selecione o usuário
    • Agora você tem acesso as duas chaves de acesso (publica e privada). Selecione o usuário

Configurando as Variáveis de Ambiente

Crie um arquivo .env na raiz do projeto e adicione as seguintes variáveis:

AWS_ACCESS_KEY_ID=sua_chave_publica
AWS_SECRET_ACCESS_KEY=sua_chave_privada
AWS_S3_BUCKET_NAME=nome_do_seu_bucket
AWS_S3_REGION=sua_região

Assegure-se de adicionar o arquivo .env ao seu .gitignore para manter as credenciais seguras.

Criando o Serviço de Upload

Vamos criar um serviço que encapsula a lógica de upload para o S3.

Estrutura de Diretórios

src/
├── upload/
│   ├── upload.module.ts
│   ├── upload.service.ts
│   └── upload.controller.ts

Código do Serviço

src/upload/upload.service.ts

import { Injectable } from '@nestjs/common';
import * as AWS from 'aws-sdk';
import { ConfigService } from '@nestjs/config';
import { Multer } from 'multer';

@Injectable()
export class UploadService {
  private s3: AWS.S3;
  private bucketName: string;

  constructor(private configService: ConfigService) {
    this.s3 = new AWS.S3({
      accessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
      secretAccessKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
      region: this.configService.get<string>('AWS_S3_REGION'),
    });
    this.bucketName = this.configService.get<string>('AWS_S3_BUCKET_NAME');
  }

  async uploadFile(file: Multer.File): Promise<AWS.S3.ManagedUpload.SendData> {
    const params: AWS.S3.PutObjectRequest = {
      Bucket: this.bucketName,
      Key: `${Date.now().toString()}-${file.originalname}`,
      Body: file.buffer,
      ACL: 'public-read',
      ContentType: file.mimetype,
    };

    return this.s3.upload(params).promise();
  }
}

Criando o Controller de Upload

O controller irá expor um endpoint para receber os arquivos e delegar o upload para o serviço.

src/upload/upload.controller.ts

import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { UploadService } from './upload.service';
import { Multer } from 'multer';

@Controller('upload')
export class UploadController {
  constructor(private readonly uploadService: UploadService) {}

  @Post()
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(@UploadedFile() file: Multer.File) {
    const result = await this.uploadService.uploadFile(file);
    return {
      url: result.Location,
    };
  }
}

Configurando o Módulo de Upload

src/upload/upload.module.ts

import { Module } from '@nestjs/common';
import { UploadController } from './upload.controller';
import { UploadService } from './upload.service';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule],
  controllers: [UploadController],
  providers: [UploadService],
})
export class UploadModule {}

Atualizando o Módulo Principal

Certifique-se de importar o módulo de upload no módulo principal da aplicação.

src/app.module.ts

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { UploadModule } from './upload/upload.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    UploadModule,
  ],
})
export class AppModule {}

Testando o Upload de Arquivos

Agora que tudo está configurado, vamos testar o endpoint de upload.

  1. Inicie a Aplicação

    npm run start
    
  2. Use o Postman ou Insomnia para Testar

    • Método: POST
    • URL: http://localhost:3000/upload
    • Body: Selecione form-data, adicione um campo file do tipo File e selecione o arquivo que deseja fazer upload.

    Aqui coloca uma imagem mostrando a configuração no Postman.

  3. Verifique a Resposta

    A resposta deverá conter a URL pública do arquivo armazenado no S3.

    {
      "url": "https://nome_do_seu_bucket.s3.sua-região.amazonaws.com/1234567890-seuarquivo.ext"
    }
    
  4. Verifique no S3

    Acesse o console do S3 e verifique se o arquivo foi carregado no bucket correto.

Considerações Finais

Integrar o Amazon S3 com NestJS para upload de arquivos públicos é uma maneira eficiente de gerenciar recursos estáticos em sua aplicação. Este guia abordou os passos essenciais para configurar o serviço, mas existem várias otimizações e funcionalidades adicionais que você pode implementar, como:

  • Validação de Tipos de Arquivo: Assegure-se de que apenas tipos de arquivos permitidos sejam enviados.
  • Limitação de Tamanho: Evite uploads de arquivos muito grandes que possam afetar o desempenho.
  • Gerenciamento de Erros: Implemente um tratamento de erros robusto para lidar com falhas no upload.
  • URLs Temporárias: Para maior segurança, considere gerar URLs temporárias para acesso aos arquivos.

Explore essas possibilidades para aprimorar ainda mais sua aplicação!

Repositório no GitHub

Para acessar o código fonte deste projeto, visite o Acesse o Repositório no GitHub.


Espero que este guia tenha sido útil para você integrar o Amazon S3 em sua aplicação NestJS.

Olá Dev 👋🏻

Se você achou este post útil, considere dar uma estrela no repositório do GitHub ou compartilhar nas suas redes sociais favoritas 😍. Seu apoio faria toda a diferença!

Dúvidas? 🙋

Se tiver alguma pergunta sobre desenvolvimento backend, sinta-se à vontade para criar uma nova issue no GitHub usando o botão abaixo. Ficarei feliz em ajudar com qualquer assunto que você queira explorar!
Compartilhar conhecimento é a melhor forma de crescermos juntos 👨🏻‍💻.
Me faça uma pergunta
Back to Blog

Posts relacionados

Ver todos os posts »
Guia Completo dos Comandos CLI do NestJS

Guia Completo dos Comandos CLI do NestJS

Aprenda a utilizar a CLI do NestJS de forma eficiente com este guia completo. Descubra os principais comandos, entenda para que cada um serve e veja o que eles geram em seu projeto.