بهترین عملکرد Nest.Js – انجمن DEV

امروز، بیایید به یک جنبه حیاتی از توسعه نرم افزار بپردازیم: نوشتن کد تمیزتر و قابل نگهداری تر.
یکی از موثرترین راهها برای رسیدن به این هدف، استفاده از قدرت TypeScript در برنامههای NestJS ما است.
پس از ایجاد برنامه NestJS، اغلب متوجه خواهید شد که منابعی را برای برنامه خود ایجاد می کنید، مانند:
nest g res test
این دستور یک منبع جدید مانند یک کنترلر، سرویس و ماژول تولید می کند. در ابتدا، این رویکرد به خوبی کار می کند.
با این حال، همانطور که برنامه شما رشد می کند و شروع به ایجاد منابع بیشتر می کنید، یک الگوی مشترک را مشاهده خواهید کرد: تکرار کد.
مشکل: تکرار کد
هنگامی که برنامه خود را ایجاد می کنید، به راحتی می توانید متوجه شوید که یک کد یکسان یا مشابه را بارها و بارها تکرار می کنید. خواه در کنترلرها، سرویس ها یا مخازن باشد، نگهداری، آزمایش و گسترش این کد تکراری به سرعت دشوار می شود.
راه حل: DRY را در آغوش بگیرید
اینجاست که اصل DRY (خودت را تکرار نکن) وارد عمل می شود. اصل DRY ما را تشویق میکند تا کدهای تکراری را حذف کنیم و برنامههایمان را آسانتر، کارآمدتر و مقیاسپذیرتر نگه داریم. بنابراین، چگونه می توانیم از این مشکل عملکرد و نگهداری جلوگیری کنیم؟
Refactoring برای DRY
برای نشان دادن، بیایید نگاهی دقیقتر به برخی از روشهای رایج برای اصلاح و بهبود کد با استفاده از ویژگیهای TypeScript بیندازیم:
ایجاد خدمات قابل استفاده مجدد:
به جای تکرار منطق در هر کنترلکننده، یک کنترلکننده و سرویس انتزاعی با روشهای قابل استفاده مجدد ایجاد کنید که عملیاتهای رایجی مانند اعتبارسنجی دادهها، رسیدگی به خطاها یا کوئریهای پایگاه داده را مدیریت میکند.
از Generics استفاده کنید:
ژنریک های TypeScript می تواند یک راه عالی برای کاهش افزونگی باشد. با تعریف توابع یا کلاس های عمومی، می توانید انواع داده های مختلف را بدون تکرار منطق یکسان برای هر نوع مدیریت کنید.
از وراثت و رابط ها استفاده کنید:
در برنامه نویسی شی گرا (OOP)، وراثت به شما این امکان را می دهد که منطق مشترک را در کلاس های پایه انتزاع کنید. به طور مشابه، اینترفیس ها می توانند اطمینان حاصل کنند که اجزای مختلف بدون منطق تکراری به یک ساختار می چسبند.
ایجاد ماژول های مشترک:
NestJS به شما امکان میدهد سرویسها، کنترلکنندهها و ارائهدهندگان مرتبط را در ماژولهای مشترک قرار دهید، بنابراین لازم نیست آنها را در برنامه خود تکرار کنید. این رویکرد سازماندهی بهتر و استفاده مجدد از کد را ترویج می کند.
بیایید به بررسی این موضوع بپردازیم که چگونه میتوانید لایههای کنترلر و سرویس را در برنامه NestJS خود بازسازی کنید تا از تکرار کد جلوگیری کنید و قابلیت نگهداری را بهبود ببخشید. ما همچنین نشان خواهیم داد که چگونه با ایجاد یک CrudService قابل استفاده مجدد، از عملکرد داخلی TypeORM استفاده کنیم.
مرحله 1: مؤلفه و سرویس تست قبل از Refactor
قبل از اینکه دوباره فاکتور کنیم، اجازه دهید نگاهی به کد اصلی TestController و TestService بیندازیم:
در این پیاده سازی، TestService تمام عملیات CRUD را به صورت دستی تعریف می کند. در حالی که این برای برنامه های کوچک خوب کار می کند، با رشد پروژه ناکارآمد می شود و همان منطق در هر سرویس تکرار می شود.
مرحله 2: معرفی کلاس CrudService
برای اصلاح و بهینهسازی، میتوانیم یک CrudService عمومی را معرفی کنیم که شامل عملیات CRUD رایج برای موجودیتهای TypeORM است. CrudService از منطق داخلی TypeORM برای عملیات پایگاه داده استفاده می کند، که رسیدگی به وظایف CRUD را آسان تر می کند.
در اینجا CrudService است که ما در سرویس بازسازی شده خود استفاده خواهیم کرد:
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
@Injectable()
export abstract class CrudService {
constructor(private repository: Repository) {}
async save(entity) {
return await this.repository.save(entity);
}
async findAll() {
return await this.repository.find({});
}
async remove(id: string) {
return await this.repository.delete(id);
}
}
این CrudService یک کلاس انتزاعی است که می تواند توسط هر سرویسی که نیاز به مدیریت عملیات CRUD برای موجودیت های TypeORM دارد، گسترش یابد. این شامل روشهایی برای ذخیره، یافتن همه، و حذف موجودیتها است که همگی توسط مخزن TypeORM پشتیبانی میشوند.
مرحله 3: Refactoring TestService
اکنون، بیایید TestService را برای گسترش CrudService تغییر دهیم و از منطق TypeORM استفاده کنیم. با انجام این کار، نیازی به نوشتن دستی عملیات CRUD در هر سرویس را از بین میبریم و در عوض، از منطق ارائه شده توسط CrudService استفاده مجدد میکنیم.
در اینجا TestService به روز شده است:
import { Injectable } from '@nestjs/common';
import { CrudService } from 'src/utils/crud.service';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TestEntity } from './entities/test.entity';
@Injectable()
export class TestService extends CrudService{
constructor(
@InjectRepository(TestEntity)
private testEntityRepository: Repository,
) {
super(testEntityRepository)
}
}
توجه کنید که چگونه TestService اکنون CrudService را گسترش داده و از مخزن TestEntity استفاده می کند. این سرویس دیگر نیازی به تعریف ایجاد، findAll، حذف و سایر متدهای CRUD ندارد. اینها از CrudService به ارث رسیده اند و به ما امکان می دهند روی منطق خاص TestEntity خود تمرکز کنیم.
مرحله 4: بازسازی TestController
اکنون بیایید به TestController بازسازی شده نگاه کنیم. از آنجایی که TestService از قبل عملیات CRUD را مدیریت می کند، می توانیم کنترل کننده را ساده کنیم:
import { Controller } from '@nestjs/common';
import { TestService } from './test.service';
import { CreateTestDto } from './dto/create-test.dto';
import { UpdateTestDto } from './dto/update-test.dto';
import { BaseController } from './abstract.controller';
@Controller('test')
export class TestController extends BaseController {
constructor(private readonly testService: TestService) {
super(testService);
}
}
مزایای این رویکرد
با معرفی CrudService و بازسازی TestService و TestController به موارد زیر دست پیدا می کنیم:
لایه ساده شده: دیگر نیازی به نوشتن عملیات CRUD تکراری نداریم. BaseController و CrudService تمام منطق اولیه را مدیریت می کنند.
کاهش تکرار کد: QUERIES مشترک و منطق CRUD در یک مکان متمرکز شدهاند و باعث میشود پایگاه کد تمیزتر و نگهداری آن آسانتر شود.
یکپارچه سازی TypeORM: CrudService از الگوی مخزن TypeORM استفاده می کند، بنابراین تمام عملیات پایگاه داده به طور موثر و پیوسته انجام می شود.
مقیاسسازی آسانتر: هنگام افزودن موجودیتهای جدید، میتوانید به سادگی یک سرویس جدید ایجاد کنید که CrudService را گسترش داده و مخزن مربوطه را تزریق کنید.
نتیجه گیری
با بازسازی TestService و TestController برای استفاده از BaseController و CrudService، کد خود را سادهسازی میکنیم و بهترین روشها مانند DRY (خودت را تکرار نکن) دنبال میکنیم.
این رویکرد نه تنها کد را ساده می کند، بلکه برنامه را مقیاس پذیرتر و قابل نگهداری تر می کند.