Provider - 提供服務的供應商

關於 Provider

緊接著登場的是 Provider,它是提供後端服務的主要角色,在前面的範例當中我們沒有處理過多的邏輯,可以想像如果將所有複雜的運算都放在 Controller 裡,將會變得難以維護,且也失去了一部分的彈性和擴充性,因此把這些運算的邏輯單獨拉出來成 service 可以讓整體的架構更清晰有序,也能更模組化的切分功能出來。

創建 Provider

和先前的 Controller 一樣,我們可以透過 nest g service <name> 來快速建立 service 檔案,如果先前已經有建立同名的資料夾的話,就會自動的把 service 檔案放到對應的目錄裡面。

初始化後的檔案應該會如下面這樣:

import { Injectable } from '@nestjs/common';

@Injectable()
export class ComputersService {}

其中 @Injectable() 這個裝飾器就表示底下的這個類別是可以被注入的,簡單來說就是可以被傳入到 Controller 當中進行運用。

拓展服務內容

針對剛剛建立的 Provider,可以稍微拓展一下該類別當中的函式內容,例如:

@Injectable()
export class ComputersService {
  private readonly computers: Computer[] = [];

  create(computer: Computer): void {
    this.computers.push(computer);
  }

  findAll(): Computer[] {
    return this.computers;
  }
}

這裡的 Computer 型別習慣上會另外建立一個 .entity.ts 來宣告,以利後續的維護擴充:

// /computers/entities/computer.entity.ts

export class Computer {
  public readonly id: number;
  public title: string;
  public description: string;

  constructor(id: number, title: string, description: string) {
    this.id = id;
    this.title = title;
    this.description = description;
  }
}

寫好 Provider 的服務內容之後就可以在 Controller 裡將 Provider 注入進去,使用到的是 constructor,Nest 會在此處把注入進來的 service 以 private 屬性實例化,並可以讓底下的函式可以使用 service 內的各個方法。

@Controller('computers')
export class ComputersController {
  // 透過建構式來將服務注入到控制器中
  constructor(private readonly computersService: ComputersService) {}

  @Get()
  findAll(): Computer[] {
    return this.computersService.findAll();
  }

  @Post()
  create(@Body() dto: CreateComputersDto) {
    return this.computersService.create(
      new Computer(1, dto.title, dto.description || ''),
    );
  }
}

Copyright© 2026 ZeoXer. All Rights Reserved.