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