Hur man bygger ett Nest.js CRUD REST API med TypeORM och PostgreSQL

By rik

Precis som andra ramverk för Node.js erbjuder Nest.js ett omfattande utbud av verktyg för att skapa robusta och skalbara backend-tjänster. Det är dock avgörande att förstå hur man effektivt implementerar grundläggande operationer som att skapa, läsa, uppdatera och ta bort (CRUD), som är de mest grundläggande funktionerna i API-utveckling.

Denna guide visar hur du bygger ett Nest.js CRUD REST API med TypeORM och en PostgreSQL-databas.

Komma igång med Nest.js

För att börja, installera Nest.js kommandoradsverktyg (CLI) med följande kommando:

 npm i -g @nestjs/cli 

Skapa sedan ett nytt projekt genom att köra:

 nest new crud-app 

CLI-verktyget kommer att be dig att välja en pakethanterare; välj den som du föredrar. I det här exemplet använder vi npm, Node Package Manager.

CLI:n genererar ett grundläggande Nest.js-projekt med alla nödvändiga konfigurationsfiler och initiala beroenden som krävs för att köra applikationen.

Navigera sedan till projektkatalogen och starta utvecklingsservern:

 cd crud-app
npm run start

Du hittar den fullständiga koden för det här projektet i dess GitHub-förvar.

Skapa en PostgreSQL-databas

Denna handledning använder en PostgreSQL-molninstans, men du kan också konfigurera en lokal PostgreSQL-databas. Du kan installera PostgreSQL på Windows, macOS eller Linux.

Så här konfigurerar du en PostgreSQL-molninstans:

  • Gå till ElephantSQL, registrera dig och logga in på ditt kontos översiktssida.
  • Klicka på knappen ”Skapa ny instans” längst upp till vänster på sidan för att skapa en ny instans för din applikation.
  • Ange ett namn för din instans, välj den kostnadsfria planen och den önskade regionen för att slutföra installationsprocessen.
  • När databasinstansen har skapats, gå till inställningssidan och kopiera den angivna databasens URL.

Konfigurera databasanslutningen

Skapa en fil med namnet `.env` i projektets rotkatalog och klistra in databasens anslutnings-URL enligt nedan:

 DATABASE_URL="<din anslutnings-URL här>" 

Installera nu dessa nödvändiga paket:

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

Skapa sedan en databasmodul med CLI-verktyget:

 nest g module database 

Öppna filen `database/database.module.ts` och lägg till följande databaskonfigurationskod:

 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 {}

Denna databasmodul hanterar anslutningen genom att konfigurera TypeORM-modulen med den nödvändiga anslutningsparametern, databasens URL.

Dessutom definierar den `User`-entiteten som en del av konfigurationen, vilket specificerar strukturen och egenskaperna för den data som lagras i PostgreSQL-databastabellen.

I detta skede kommer koden troligen att ge ett fel eftersom du ännu inte har skapat användarenheten. Du kommer att göra det i nästa steg.

Uppdatera filen `app.module.ts`

Uppdatera nu huvudapplikationsmodulen för att inkludera konfigurationen för databasmodulen:

 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 {}

Definiera en användarmodul

Användarmodulen fungerar som en centraliserad komponent, som ansvarar för att inkapsla och hantera logiken som krävs för att implementera API:ets CRUD-funktionalitet.

Kör följande terminalkommando för att skapa API:ets användarmodul:

 nest g module users 

CLI-verktyget kommer automatiskt att uppdatera filen `app.module.ts` för att återspegla de ändringar som gjorts, förutom att skapa användarmodulen. Detta säkerställer att den nyskapade modulen, ”users”, är korrekt integrerad i applikationens modulkonfiguration.

Skapa en användarenhet

TypeORM är ett ORM-bibliotek (Object-Relational Mapping) som förenklar databasinteraktioner i applikationer som använder TypeScript genom att mappa JavaScript-objekt till databastabeller.

Genom att skapa en `User`-entitet med TypeORM definierar du strukturen och egenskaperna för användardata i PostgreSQL-databasen.

Skapa en ny fil `models/user.entity.ts` i användarkatalogen och lägg till följande kod:

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

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

@Column()
name: string;

@Column()
email: string;
}

`User`-entiteten definierar strukturen för användardata som lagras i databasen. I detta fall är `id` en primärnyckelkolumn och det finns kolumner för `name` och `email` samt deras motsvarande egenskaper.

Skapa CRUD API-tjänsten

Skapa nu API-tjänsten som hanterar logiken för CRUD-operationerna genom att köra kommandot nedan:

 nest g service users 

Öppna filen `user-auth.service.ts` och lägg till följande kod:

 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);
}
}

Klassen `UsersService` definierar olika API-metoder som hanterar CRUD-operationer. Dessa metoder inkluderar att hämta alla användares data, hitta en specifik användare med deras ID, skapa en ny användare, uppdatera en befintlig användare och radera en användare i databasen.

Definiera en styrenhet för API

Skapa en styrenhet som hanterar API-slutpunkterna för de användarrelaterade operationerna:

 nest g controller users 

Lägg sedan till följande kod i filen `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' };
}
}

Styrenheten hanterar API-slutpunkter för användaroperationer. Den hanterar GET-förfrågningar för att hämta alla användare, POST-förfrågningar för att skapa nya användare, PUT-förfrågningar för att uppdatera befintliga användare och DELETE-förfrågningar för att ta bort användare.

Genom att använda `UsersService` och interagera med `User`-entiteten tillhandahåller denna styrenhet ett komplett API för att hantera användarrelaterade operationer på data som lagras i databasen.

Uppdatera filen `users.module.ts`

Uppdatera nu filen `users.module.ts` enligt nedan för att säkerställa att du införlivar `User`-entiteten och TypeORM-modulen, vilket upprättar anslutningen till databasen.

 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 {}

Starta nu utvecklingsservern för att testa CRUD-operationerna med verktyg som Postman:

 npm run start 

Servern startar på port 3000, och du kan skicka API-förfrågningar till http://localhost:3000/api/users.

Bygga backend-applikationer med Nest.js

Oavsett om du utvecklar ett enkelt REST API eller en komplex webbapp, erbjuder Nest.js en omfattande uppsättning funktioner och möjligheter för att skapa ett pålitligt och robust backend-system.

Nest.js erbjuder en mer strukturerad metod för projektutveckling än vad Express.js gör. Detta säkerställer att du tryggt kan bygga, skala och underhålla komplexa applikationer, tack vare dess organiserade och modulära designmönster.