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 || ''), ); } }