學習筆記:Nest.js 和後端的幾個概念

AurLemon發表於2024-09-06

前言

今天嘗試寫了個 Nest.js 的 Demo,但是發現好像一堆東西看不懂,拿 AI 問了下才知道具體是什麼,把 AI 說的總結了一下放著自己看。(所以這篇文章帶了 AI 輔助生成的標籤)

概念

Nest.js 是一個基於 Node.js 構建的進階框架,它使用 TypeScript 編寫,具備模組化、依賴注入等特性,幫助開發者快速構建高效能和可擴充套件的服務端應用。Nest.js 是圍繞著 物件導向程式設計(OOP)依賴注入(DI) 的設計理念開發的。

模組化結構

概念

在 Nest.js 中,應用是由多個模組(Module)組成的,模組包含控制器(Controller)、服務(Service)、提供者(Provider)等。每個模組可以將業務邏輯分離成獨立的單元,使程式碼易於維護和擴充套件。

案例

以 AppModule 為例。

import { Module } from '@nestjs/common';
import { TodoController } from './todo/todo.controller';
import { TodoService } from './todo/todo.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Todo } from './todo/todo.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'todo.db',
      entities: [Todo],
      synchronize: true,
    }),
    TypeOrmModule.forFeature([Todo]),
  ],
  controllers: [TodoController],
  providers: [TodoService],
})
export class AppModule {}
  • @Module():標記為一個模組,它包含了控制器和服務。透過 imports 引入 TypeORM 配置來連線資料庫。
  • controllers:定義了哪些控制器處理 HTTP 請求。
  • providers:註冊服務(例如 TodoService),這些服務可以在整個模組中被使用。

控制器(Controller)

概念

控制器用於處理 HTTP 請求(如 GET、POST、PUT、DELETE 等),它負責接受客戶端的請求並將其轉發給服務層處理。Nest.js 中的控制器是透過 @Controller() 裝飾器定義的。

案例

以TodoController 為例。

import { Controller, Get, Post, Delete, Param, Body } from '@nestjs/common';
import { TodoService } from './todo.service';
import { Todo } from './todo.entity';

@Controller('todos')
export class TodoController {
  constructor(private readonly todoService: TodoService) {}

  @Get()
  getAllTodos(): Promise<Todo[]> {
    return this.todoService.findAll();
  }

  @Post()
  createTodo(@Body('title') title: string): Promise<Todo> {
    return this.todoService.create(title);
  }

  @Delete(':id')
  deleteTodo(@Param('id') id: number): Promise<void> {
    return this.todoService.remove(id);
  }
}

解釋

  • @Controller('todos'):將控制器定義為 /todos 路徑下的所有請求處理器。
  • constructor(private readonly todoService: TodoService):透過依賴注入將 TodoService 注入到控制器中。
  • @Get():處理 GET 請求,呼叫 todoService 獲取所有任務。
  • @Post():處理 POST 請求,建立新的任務。
  • @Delete(':id'):處理 DELETE 請求,刪除指定 ID 的任務。

服務(Service)

概念

服務是用來處理業務邏輯的類。服務通常透過依賴注入的方式被控制器呼叫,並負責與資料庫或其他外部資源互動。

案例:

以 TodoService 為例。

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Todo } from './todo.entity';

@Injectable()
export class TodoService {
  constructor(
    @InjectRepository(Todo)
    private readonly todoRepository: Repository<Todo>,
  ) {}

  async create(title: string): Promise<Todo> {
    const newTodo = this.todoRepository.create({ title, completed: false });
    return this.todoRepository.save(newTodo);
  }

  async findAll(): Promise<Todo[]> {
    return this.todoRepository.find();
  }

  async remove(id: number): Promise<void> {
    await this.todoRepository.delete(id);
  }
}

解釋

  • @Injectable():標記 TodoService 類為可被注入的服務,Nest.js 會自動建立並管理它的例項。
  • @InjectRepository(Todo):注入 Todo 實體的倉庫,用於與資料庫表互動。
  • create():建立新任務,並儲存到資料庫。
  • findAll():從資料庫中獲取所有任務。
  • remove():根據任務 ID 刪除任務。

依賴注入(Dependency Injection,DI)

概念

依賴注入是 Nest.js 的核心概念之一。透過 DI,類的依賴物件(如服務)可以在類的建構函式中被自動注入,避免類自己管理依賴的建立過程。DI 使得程式碼更易測試和維護。

案例:控制器中的依賴注入

constructor(private readonly todoService: TodoService) {}

解釋

  • todoService 是透過依賴注入注入到控制器中的。在 AppModule 中註冊的 TodoService 會自動被注入。

實體(Entity)與 TypeORM

概念

實體(Entity)表示資料庫中的表結構,TypeORM 允許開發者使用物件導向的方式與資料庫互動。每個實體類都對應資料庫中的一張表。

案例

以 Todo 實體為例。

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

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

  @Column()
  title: string;

  @Column({ default: false })
  completed: boolean;
}

解釋

  • @Entity():將 Todo 類標記為資料庫表。
  • @PrimaryGeneratedColumn():定義了一個自增的主鍵 id 列。
  • @Column():定義了表的普通列,如 title(任務標題)和 completed(任務是否完成)。

非同步

因為資料庫操作通常是非同步的,Nest.js 透過 Promise 來處理這些非同步操作。Promise<T> 表示這個操作最終會返回一個 T 型別的值(例如 Todo)。

async create(title: string): Promise<Todo> {
  const newTodo = this.todoRepository.create({ title, completed: false });
  return this.todoRepository.save(newTodo);
}
  • Promise<Todo>:表示這個非同步操作最終會返回一個 Todo 實體。
  • asyncawait:允許我們以同步的方式編寫非同步程式碼。

總結

  • Nest.js 是模組化和依賴注入驅動的框架:每個應用由模組、控制器和服務組成,模組管理控制器和服務,服務處理業務邏輯並透過依賴注入與控制器協作。
  • TypeORM 提供資料庫互動能力:透過實體類與資料庫表進行對映,Repository 提供對資料庫的增刪查改操作。
  • 依賴注入減少了類與類之間的耦合:Nest.js 自動管理類的依賴,提升了程式碼的靈活性和可維護性。

相關文章