Como criar uma API REST CRUD do Nest.js usando TypeORM e PostgreSQL
O Nest.js, semelhante a outras estruturas Node.js, oferece um conjunto extenso de ferramentas para criar serviços de back-end robustos e escaláveis. No entanto, é crucial ter uma sólida compreensão de como implementar eficazmente as operações CRUD - criar, ler, atualizar e eliminar - que formam a base do desenvolvimento de API.
Familiarize-se com o processo de criação de uma API Restful habilitada para CRUD utilizando a estrutura Nest.js, em conjunto com a biblioteca TypeORM e um banco de dados PostgreSQL.
Getting Started With Nest.js
Proceda à instalação da ferramenta de interface de linha de comandos Nest.js para facilitar o processo de desenvolvimento.
npm i -g @nestjs/cli
Em seguida, crie um novo projeto executando:
nest new crud-app
Seleccione um gestor de pacotes entre as seguintes opções:npm, o gestor de pacotes Node, é recomendado para utilização neste projeto.
Uma interface de linha de comandos (CLI) irá gerar um projeto Nest.js padrão, incluindo os ficheiros de configuração necessários e as dependências iniciais para operar a aplicação.
Por fim, dirija a sua atenção para o diretório do projeto e inicie o funcionamento do servidor de desenvolvimento.
cd crud-app
npm run start
O código-fonte deste projeto está acessível através do repositório GitHub que lhe está associado.
Criar um banco de dados PostgreSQL
no Windows, o instalador pode ser baixado do site oficial; no macOS, ele pode ser instalado via Homebrew executando brew install postgres; e no Linux, o gerenciador de pacotes específico da distribuição deve ser usado para instalar o servidor.
Para configurar uma instância do PostgreSQL na nuvem:
⭐ Acesse ElephantSQL , inscreva-se e faça login na página de visão geral da sua conta.
⭐ Clique no botãoCreate New Instance na secção superior esquerda da página para criar uma nova instância para a sua aplicação.
Depois de ter criado a instância da base de dados, navegue para a página de definições e obtenha o URL da base de dados fornecido.
Configurar a ligação à base de dados
Na pasta de raiz do seu projeto, crie um ficheiro chamado “.env” e preencha-o com o URL de ligação à base de dados utilizando o seguinte formato:
DATABASE_URL="<your connection url here>"
Agora instale estes pacotes:
npm install pg typeorm @nestjs/typeorm @nestjs/config
Prossiga com a criação de um módulo de base de dados utilizando a ferramenta de interface de linha de comandos.
nest g module database
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 {}
O módulo de base de dados acima mencionado facilita o estabelecimento de uma ligação utilizando o módulo TypeORM e especificando os parâmetros de ligação necessários, incluindo o URL da base de dados.
A declaração acima mencionada delineia a entidade Utilizador como um componente integral da configuração que engloba os detalhes estruturais e de propriedade relativos aos dados que estão a ser preservados na tabela da base de dados PostgreSQL.
Por favor, crie a entidade utilizador antes de prosseguir com os passos seguintes. O processo de criação de uma nova entidade para os utilizadores é apresentado nas etapas seguintes.
Atualizar o ficheiro app.module.ts
Por fim, modifique o módulo principal da aplicação para incorporar as configurações necessárias para o módulo da base 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 utilizadores
O módulo de utilizadores funciona como um elemento de consolidação, englobando e controlando a propriedade intelectual necessária para executar as operações de criação, leitura, atualização e eliminação da API.
nest g module users
O utilitário da interface de linha de comandos modifica eficazmente o ficheiro app.module.ts para refletir as actualizações efectuadas e também cria um módulo de utilizador. Isto garante que o módulo recentemente adicionado, denominado ‘users’, é efetivamente incorporado na configuração do módulo da aplicação.
Criar uma entidade de usuário
TypeORM é uma biblioteca que facilita a utilização de bancos de dados em aplicativos desenvolvidos com TypeScript, fornecendo uma interface entre objetos JavaScript e estruturas de tabela em um banco de dados relacional.
Através da utilização do TypeORM, a criação de uma entidade User resulta na delineação da conformação e atributos dos dados do utilizador dentro da tabela da base de dados PostgreSQL.
O processo de criação de um novo arquivo na pasta “models” dentro do diretório “users” envolve a implementação de uma entidade conhecida como “User”. Para tal, é possível utilizar TypeScript, compondo um ficheiro relevante com o código apropriado.
import { Entity, PrimaryGeneratedColumn, Column, } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
A entidade User representa a organização dos dados do utilizador na base de dados, com o identificador a servir de atributo chave único e as colunas Name e Email a especificarem detalhes adicionais sobre cada utilizador.
Criar o serviço da API CRUD
Posso sugerir uma frase mais refinada?
nest g service users
O conteúdo do ficheiro “user-auth.service.ts” já é fornecido na sua totalidade, pelo que não é necessário adicionar mais código. O bloco de código que foi adicionado anteriormente contém um serviço que lida com a autenticação para o aplicativo usando a Autenticação do Firebase.
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);
}
}
A classe UserServicecompreende vários métodosAPI relacionados com o tratamento das operaçõesCRUD.Estes métodos incluem a facilitação da extração de dados de todos os utilizadores, a obtenção de um utilizador individual através do seu número de identificação, a produção de um novo utilizador completo, a atualização de um utilizador existente e, por último, a erradicação de dados deserializados através da valorização de um código de identificação específico de um utilizador efetivo na base de dados do Nexus.
Definir um controlador para a API
A implementação de um controlador é necessária para supervisionar e controlar a gestão dos pontos finais da interface de programação de aplicações (API) relativos a tarefas relacionadas com o utilizador.
nest g controller users
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 é responsável por supervisionar os vários pontos finais associados às operações do utilizador. Isto inclui o tratamento de pedidos Get para obter uma lista de todos os Utilizadores, pedidos Post para registar novos Utilizadores, pedidos Put para modificar Utilizadores existentes e pedidos Delete para remover Utilizadores do sistema.
Através da implementação do UsersService e da sua interação com a entidade User, este controlador oferece uma interface abrangente para o tratamento de todas as tarefas operacionais relacionadas com os utilizadores e os seus dados associados armazenados na base de dados.
Atualizar o ficheiro users.module.ts
Incorporar a entidade
User
e o módulo
TypeORM
no ficheiro
users.module.ts
, assegurando que estão devidamente integrados entre si para estabelecer uma ligação funcional à base 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, sinta-se à vontade para ativar o servidor de desenvolvimento e empregar o Postman para experimentar o CRUD
npm run start
O servidor iniciará na porta 3000, e pode enviar pedidos de API para ele em http://localhost:3000/api/users .
Construir aplicações de backend com Nest.js
A utilização de Nest.js permite a criação de uma API Rest descomplicada, bem como de uma aplicação Web multifacetada, com a sua gama abrangente de funcionalidades e capacidades que fornecem os meios para estabelecer uma plataforma de backend sólida e resiliente.
O Nest.js fornece uma metodologia mais sistemática para o desenvolvimento de projectos em comparação com o Express.js, promovendo assim uma maior confiança na construção, dimensionamento e manutenção de aplicações complexas devido ao seu estilo arquitetónico bem organizado e modular.