Como construir uma API REST CRUD Nest.js usando TypeORM e PostgreSQL

Como outras estruturas do Node.js, o Nest.js fornece um kit de ferramentas abrangente para criar serviços de back-end robustos e escalonáveis. No entanto, é importante entender como implementar as operações de criação, leitura, atualização e exclusão (CRUD) no Nest.js com eficiência — essas são as operações mais fundamentais no desenvolvimento de APIs.

Saiba como criar uma API REST CRUD Nest.js usando TypeORM e um banco de dados PostgreSQL.

Introdução ao Nest.js

Para começar, instale a ferramenta de linha de comando Nest.js:

 npm i -g @nestjs/cli 

Em seguida, crie um novo projeto executando:

 nest new crud-app 

A ferramenta CLI solicitará que você escolha um gerenciador de pacotes, escolha a opção que achar mais preferível. Usaremos o npm, o gerenciador de pacotes do Node.

A CLI criará um projeto Nest.js básico com todos os arquivos de configuração necessários e as dependências iniciais necessárias para executar o aplicativo.

Por fim, navegue até o diretório do projeto e inicie o servidor de desenvolvimento.

 cd crud-app
npm run start

Você pode encontrar o código deste projeto em seu GitHub repositório.

Criar um banco de dados PostgreSQL

Este tutorial usa uma instância do PostgreSQL na nuvem, mas você pode configurar um banco de dados PostgreSQL local. Você pode instalar o PostgreSQL no Windows, no macOS ou no Linux.

Para configurar uma instância do PostgreSQL na nuvem:

  • Dirija-se a ElefanteSQLinscreva-se e faça login na página de visão geral da sua conta.
  • Clique no botão Criar nova instância na seção superior esquerda da página para criar uma nova instância para seu aplicativo.
  • Preencha o nome da sua instância, escolha o plano gratuito e, por fim, selecione a região para concluir o processo de configuração.
  • Depois de criar a instância do banco de dados, vá para a página de configurações e copie o URL do banco de dados fornecido.
  •   Como cancelar o Amazon FreeTime sem dispositivo

    Configurar a conexão do banco de dados

    No diretório raiz do seu projeto, crie um arquivo .env e cole a URL de conexão com o banco de dados da seguinte forma:

     DATABASE_URL="<your connection url here>" 

    Agora instale estes pacotes:

     npm install pg typeorm @nestjs/typeorm @nestjs/config 

    Em seguida, vá em frente e crie um módulo de banco de dados usando a ferramenta CLI.

     nest g module database 

    Abra o arquivo database/database.module.ts e adicione o seguinte código de configuração do banco de dados:

     import { Module } from '@nestjs/common';
    import { ConfigModule, ConfigService } from '@nestjs/config';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { User } from '../users/models/user.entity';

    @Module({
      imports: [
        TypeOrmModule.forRootAsync({
          imports: [ConfigModule],
          inject: [ConfigService],

          useFactory: async (configService: ConfigService) => ({
            type: 'postgres',
            url: configService.get('DATABASE_URL'),
            entities: [User],
            synchronize: true
          }),
        }),
      ],
    })

    export class DatabaseModule {}

    Este módulo de banco de dados lida com a conexão configurando o módulo TypeORM com o parâmetro de conexão necessário, a URL do banco de dados.

    Além disso, define a entidade Usuário como parte da configuração que especifica a estrutura e as propriedades dos dados armazenados na tabela do banco de dados PostgreSQL.

    Nesse estágio, seu código provavelmente gerará um erro porque você ainda não criou a entidade de usuários. Você fará isso nas etapas a seguir.

    Atualize o arquivo app.module.ts

    Por fim, atualize o módulo principal do aplicativo para incluir a configuração do módulo de banco de dados.

     import { Module } from '@nestjs/common';
    import { ConfigModule } from '@nestjs/config';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { DatabaseModule } from './database/database.module';

    @Module({
      imports: [
        ConfigModule.forRoot({
          envFilePath: '.env',
        }),
        DatabaseModule,
      ],

      controllers: [AppController],
      providers: [AppService],
    })

    export class AppModule {}

    Definir um módulo de usuários

    O módulo de usuários serve como um componente centralizado, responsável por encapsular e gerenciar a lógica necessária para implementar a funcionalidade CRUD da API.

    Execute este comando de terminal para criar o módulo de usuários da API.

     nest g module users 

    A ferramenta CLI atualiza automaticamente o arquivo app.module.ts para refletir as alterações feitas, além de criar o módulo de usuário. Isso garante que o módulo recém-criado, users, seja devidamente integrado à configuração do módulo do aplicativo.

      8 melhores ferramentas de descriptografia forense para ajudar nas investigações

    Criar uma entidade de usuário

    TypeORM é uma biblioteca Object-Relational Mapping (ORM) que simplifica as interações de banco de dados em aplicativos que usam TypeScript mapeando objetos JavaScript para tabelas de banco de dados.

    Ao criar uma entidade de usuário usando TypeORM, você define a estrutura e as propriedades dos dados do usuário no banco de dados PostgreSQL.

    No diretório de usuários, crie um novo models/user.entity.ts e adicione o seguinte código.

     import { Entity, PrimaryGeneratedColumn, Column, } from "typeorm";

    @Entity()
    export class User {
        @PrimaryGeneratedColumn()
        id: number;

        @Column()
        name: string;

        @Column()
        email: string;
    }

    A entidade Usuário define a estrutura dos dados do usuário armazenados no banco de dados. Nesse caso, é o id como a coluna de chave primária e as colunas de nome e e-mail e suas propriedades correspondentes.

    Crie o serviço de API CRUD

    Agora, crie o serviço de API que irá gerenciar a lógica das operações CRUD executando o comando abaixo:

     nest g service users 

    Abra o arquivo user-auth.service.ts e adicione este código:

     import { Injectable } from '@nestjs/common';
    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import {User} from './models/user.entity';

    @Injectable()
    export class UsersService {
      constructor(
        @InjectRepository(User)
        private userRepository: Repository<User>,
      ) {}

      async findAll(): Promise<User[]> {
        return this.userRepository.find();
      }

      async findOne(id: number): Promise<User> {
        return this.userRepository.findOne({ where: { id } });
      }

      async create(user: Partial<User>): Promise<User> {
        const newuser = this.userRepository.create(user);
        return this.userRepository.save(newuser);
      }

      async update(id: number, user: Partial<User>): Promise<User> {
        await this.userRepository.update(id, user);
        return this.userRepository.findOne({ where: { id } });
      }

      async delete(id: number): Promise<void> {
        await this.userRepository.delete(id);
      }
    }

    Essa classe UsersService define vários métodos de API dedicados ao tratamento de operações CRUD. Esses métodos incluem buscar todos os dados dos usuários, encontrar um usuário específico usando seu número de ID, criar um novo usuário, atualizar um usuário existente e um método para excluir os dados de um usuário específico no banco de dados.

      A solução definitiva para criação de diretórios

    Definir um controlador para a API

    Crie um controlador que gerenciará os endpoints da API para as operações relacionadas ao usuário.

     nest g controller users 

    Em seguida, adicione o código abaixo ao arquivo users.controller.ts.

     import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
    import { UsersService } from './users.service';
    import { User } from './models/user.entity';

    @Controller('api/users')
    export class UsersController {
      constructor(private readonly usersService: UsersService) {}

      @Get()
      async findAll(): Promise<User[]> {
        return this.usersService.findAll();
      }

      @Post()
      @HttpCode(201)
      async create(@Body() user: User): Promise<User> {
        const createdUser = await this.usersService.create(user);
        return createdUser;
      }

      @Put(':id')
      async update (@Param('id') id: number, @Body() user: User): Promise<any> {
        await this.usersService.update(id, user);
        return { message: 'User updated successfully' };
      }

      @Delete(':id')
      async delete(@Param('id') id: number): Promise<any> {
        const user = await this.usersService.findOne(id);

        if (!user) {
          throw new NotFoundException('User does not exist!');
        }

        await this.usersService.delete(id);
        return { message: 'User deleted successfully' };
      }
    }

    O controlador gerencia endpoints de API para operações do usuário. Ele lida com solicitações GET para recuperar todos os usuários, solicitações POST para criar novos usuários, solicitações PUT para atualizar usuários existentes e solicitações DELETE para excluir usuários.

    Ao utilizar o UsersService e interagir com a entidade User, este controlador fornece uma API completa para gerenciar operações relacionadas ao usuário nos dados armazenados no banco de dados.

    Atualize o arquivo users.module.ts

    Por fim, atualize o arquivo users.module.ts conforme mostrado abaixo para garantir que você incorpore a entidade User e o módulo TypeORM, que estabelece a conexão com o banco de dados.

     import { Module } from '@nestjs/common';
    import { UsersController } from './users.controller';
    import { UsersService } from './users.service';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { User } from './models/user.entity';

    @Module({
      imports: [TypeOrmModule.forFeature([User])],
      controllers: [UsersController],
      providers: [UsersService]
    })

    export class UsersModule {}

    Por fim, vá em frente e ative o servidor de desenvolvimento para testar as operações CRUD usando o Postman.

     npm run start 

    O servidor iniciará na porta 3000 e você poderá enviar solicitações de API para ele em http://localhost:3000/api/users.

    Construindo aplicativos de back-end com Nest.js

    Esteja você desenvolvendo uma API REST simples ou um aplicativo da Web complexo, o Nest.js oferece um conjunto abrangente de recursos e funcionalidades para construir um sistema de back-end confiável e robusto.

    O Nest.js oferece uma abordagem mais estruturada para o desenvolvimento de projetos do que o Express.js. Isso garante que você possa criar, dimensionar e manter com confiança aplicativos complexos, graças ao seu padrão de design organizado e modular.