Cześć, drodzy wielbiciele kodowania! Dzisiaj przysiądźmy razem przy filiżance herbaty (lub kawy, jeśli wolisz pobudkę) i pogadajmy sobie o czymś, co sprawia, że nasze życie programistyczne staje się o wiele przyjemniejsze i, uwaga… zorganizowane! 😮 Chodzi o ORM, czyli Object-Relational Mapping. Dzisiejsza historia będzie kręciła się wokół TypeScript, TypeORM i Nest.js. Przygotujcie się na porcję porad, śmiechu i żonglowania relacjami.
ORM – czyli jak przestać się martwić i pokochać relacje 💖
Zanim przejdziemy do konkretów, warto sobie przypomnieć, czym jest ORM. Otóż to magiczne narzędzie umożliwia nam pracę z bazą danych w sposób obiektowy. W praktyce oznacza to, że możemy się pozbyć irytujących, długich zapytań SQL (nie, nie mówię, że SQL to zło 😇) i przekształcić je w przyjemne dla oka i zrozumiałe operacje na obiektach. Właśnie tak, towarzysze – mówimy tu o czymś w stylu „zapytanie do bazy danych dla każdego”!
Zalety stosowania ORM 😍
A teraz kilka zalet stosowania ORM:
- Abstrakcja od konkretnej bazy danych: ORM pozwala na łatwą zmianę bazy danych bez konieczności modyfikowania kodu aplikacji.
- Czytelność: Kod staje się bardziej zrozumiały i czytelny, dzięki operacjom na obiektach zamiast surowych zapytań SQL.
- Bezpieczeństwo: ORM chroni przed wieloma atakami, takimi jak SQL Injection, poprzez stosowanie parametrów zapytań i walidacji danych.
- Produktywność: Skraca czas potrzebny na pisanie i utrzymanie kodu, dzięki gotowym mechanizmom mapowania obiektowo-relacyjnego.
- Łatwość wprowadzania zmian: ORM ułatwia wprowadzanie zmian w strukturze bazy danych, automatycznie aktualizując mapowanie obiektów.
TypeORM – bo TypeScript też potrzebuje miłości 💙
No dobrze, więc TypeScript. Każdy wie, że to silniejsza, bardziej pewna siebie wersja JavaScript (przepraszam, nie mogłem się powstrzymać 😜). A TypeORM to potężny ORM, który świetnie się integruje z TypeScriptem. Pozwala nam na wykorzystanie dekoratorów, interfejsów i innych fajnych rzeczy, które kochamy w TypeScript. Jeśli zaś chodzi o instalację i resztę to podsyłam do dokumentacji https://github.com/typeorm/typeorm – wierzę mój drogi czytelniku, że skoro to czytasz i rozumiesz o co chodzi to sobie dasz z tym radę😁
Nest.js – bo wszyscy uwielbiamy gniazdka 🐦
Nest.js to świetny framework dla Node.js, który sprawia, że pisanie aplikacji backendowych staje się dużo bardziej przemyślane i zorganizowane. Wykorzystuje on dekoratory, moduły i wiele innych fajnych funkcji. Przechodząc do sedna, zaczniemy od stworzenia prostego modelu bazy danych.
Stworzenie modelu bazy danych
![](https://enterv.pl/wp-content/uploads/2023/04/db_model-edited.webp)
Zakładając, że mamy już skonfigurowany projekt Nest.js (jeśli nie, tutaj znajdziesz jak stworzyć) oraz skonfigurowany TypeORM możemy przejść do stworzenia naszego modelu danych. Załóżmy, że mamy model User, który przechowuje informacje o naszych użytkownikach.
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@Column({ nullable: true })
age?: number;
}
Czyż nie jest to łatwe? 😎 Przy pomocy dekoratorów z TypeORM, tworzymy naszą piękną tabelę „User” z kolumnami id
, name
, email
oraz opcjonalnym polem age
.
Tworzenie modułu i serwisu
Teraz, gdy mamy już nasz model, pora na stworzenie modułu oraz serwisu w Nest.js. Zaczniemy od modułu:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UserService],
controllers: [UserController],
exports: [UserService],
})
export class UserModule {}
Nic bardziej prostego! Importujemy TypeOrmModule.forFeature([User])
, co pozwoli nam na wstrzykiwanie repozytoriów dla modelu User
w serwisie.
No to pora na serwis, który obsłuży logikę biznesową:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return await this.userRepository.find();
}
async findOne(id: number): Promise<User> {
return await this.userRepository.findOne(id);
}
async createUser(user: User): Promise<User> {
return await this.userRepository.save(user);
}
async updateUser(id: number, user: User): Promise<void> {
await this.userRepository.update(id, user);
}
async deleteUser(id: number): Promise<void> {
await this.userRepository.delete(id);
}
}
Zwróćcie uwagę na to, że nawet nie musimy tworzyć zapytań do bazy danych. TypeORM (tak jak inne systemy ORM) dostarcza nam bardzo prosty „interfejs”, dzięki czemu nie musimy się martwić o to czy dobrze napiszemy SQL’kę
Dodawanie kontrolera
![](https://enterv.pl/wp-content/uploads/2023/04/nest_db.webp)
I na koniec, dodajmy kontroler, który będzie obsługiwał zapytania HTTP:
import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from './user.entity';
@Controller('users')
export class UserController {
constructor(private userService: UserService) {}
@Get()
async findAll(): Promise<User[]> {
return this.userService.findAll();
}
@Get(':id')
async findOne(@Param('id') id: number): Promise<User> {
return this.userService.findOne(id);
}
@Post()
async createUser(@Body() user: User): Promise<User> {
return this.userService.createUser(user);
}
@Put(':id')
async updateUser(@Param('id') id: number, @Body() user: User): Promise<void> {
return this.userService.updateUser(id, user);
}
@Delete(':id')
async deleteUser(@Param('id') id: number): Promise<void> {
return this.userService.deleteUser(id);
}
}
I voilà! 🎉 Mamy gotowy kontroler, który obsługuje operacje CRUD na naszym modelu User
. Dzięki Nest.js i TypeORM tworzenie takich rzeczy jest wręcz przyjemne.
Podsumowanie
Podsumowując, używając TypeORM i Nest.js razem, możemy tworzyć nie tylko piękne, ale także wydajne aplikacje backendowe. Magia tych narzędzi pozwala na szybsze żonglowanie relacjami i kodem, pozwalając tym samym na większą wydajność pracy.
Miejmy nadzieję, że udało mi się przekazać choć odrobinę magii ORM oraz TypeScript i Nest.js. Pora na was, drodzy kodujący czytelnicy – dajcie się ponieść ORMowym falom i życzę Wam samych sukcesów w żonglowaniu relacjami! 🤹♂️
Czy zrobiłbyś jakiś poradnik dla początkujących? Bardzo mi tego tutaj brakuje 😎
Zobaczymy jeszcze. Póki co mam zaplanowane kilka wpisów, jak je wyzeruję, będę tworzyć kolejne plany 🙂
Fajny wpis