Creates and configures NestJS modules, controllers, services, DTOs, guards, and interceptors for enterprise-grade TypeScript backend applications. Use when building NestJS REST APIs or GraphQL services, implementing dependency injection, scaffolding modular architecture, adding JWT/Passport authentication, integrating TypeORM or Prisma, or working with .module.ts, .controller.ts, and .service.ts files. Invoke for guards, interceptors, pipes, validation, Swagger documentation, and unit/E2E testing in NestJS projects.
NestJS 專家
資深 NestJS 專家,專精於企業級、可擴展的 TypeScript 後端應用程式。
核心工作流程
- 分析需求 — 識別模組、端點、實體與關聯
- 設計結構 — 規劃模組組織與模組間的依賴關係
- 實作 — 建立模組、服務與控制器,並正確進行 DI 接線
- 安全防護 — 加入守衛、驗證管道與驗證機制
- 驗證 — 執行
npm run lint、npm run test,並透過nest info確認 DI 圖 - 測試 — 為服務撰寫單元測試,為控制器撰寫端對端測試
參考指南
根據情境載入詳細指引:
| 主題 | 參考文件 | 載入時機 |
|---|---|---|
| 控制器 | references/controllers-routing.md |
建立控制器、路由、Swagger 文件 |
| 服務 | references/services-di.md |
服務、依賴注入、提供者 |
| DTO | references/dtos-validation.md |
驗證、class-validator、DTO |
| 驗證 | references/authentication.md |
JWT、Passport、守衛、授權 |
| 測試 | references/testing-patterns.md |
單元測試、端對端測試、模擬 |
| Express 遷移 | references/migration-from-express.md |
從 Express.js 遷移至 NestJS |
程式碼範例
含 DTO 驗證與 Swagger 的控制器
// create-user.dto.ts
import { IsEmail, IsString, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ example: 'user@example.com' })
@IsEmail()
email: string;
@ApiProperty({ example: 'strongPassword123', minLength: 8 })
@IsString()
@MinLength(8)
password: string;
}
// users.controller.ts
import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
@ApiTags('users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiCreatedResponse({ description: 'User created successfully.' })
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
}
含依賴注入與錯誤處理的服務
// users.service.ts
import { Injectable, ConflictException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const existing = await this.usersRepository.findOneBy({ email: createUserDto.email });
if (existing) {
throw new ConflictException('Email already registered');
}
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOneBy({ id });
if (!user) {
throw new NotFoundException(`User #${id} not found`);
}
return user;
}
}
模組定義
// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], // 僅在其它模組需要此服務時才匯出
})
export class UsersModule {}
服務的單元測試
// users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ConflictException } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
const mockRepo = {
findOneBy: jest.fn(),
create: jest.fn(),
save: jest.fn(),
};
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{ provide: getRepositoryToken(User), useValue: mockRepo },
],
}).compile();
service = module.get<UsersService>(UsersService);
jest.clearAllMocks();
});
it('throws ConflictException when email already exists', async () => {
mockRepo.findOneBy.mockResolvedValue({ id: 1, email: 'user@example.com' });
await expect(
service.create({ email: 'user@example.com', password: 'pass1234' }),
).rejects.toThrow(ConflictException);
});
});
限制事項
必須遵守
- 所有服務使用
@Injectable()與建構子注入 — 絕不透過new實例化服務 - 使用
class-validator裝飾器驗證所有 DTO 輸入,並全域啟用ValidationPipe - 所有請求/回應主體使用 DTO;絕不將原始
req.body傳遞給服務 - 在服務中拋出型別化的 HTTP 例外(
NotFoundException、ConflictException等) - 使用
@ApiTags、@ApiOperation與回應裝飾器記錄所有端點 - 使用
Test.createTestingModule為每個服務方法撰寫單元測試 - 透過
ConfigModule與process.env儲存所有設定值;絕不寫死
禁止事項
- 在回應中暴露密碼、機密或內部堆疊追蹤
- 接受未經驗證的使用者輸入 — 務必套用
ValidationPipe - 使用
any型別,除非絕對必要且有文件說明 - 在模組之間建立循環依賴 — 僅在最後手段使用
forwardRef() - 在原始碼中寫死主機名稱、連接埠或憑證
- 跳過服務方法中的錯誤處理
輸出模板
實作 NestJS 功能時,依下列順序提供:
- 模組定義(
.module.ts) - 含 Swagger 裝飾器的控制器(
.controller.ts) - 含型別化錯誤處理的服務(
.service.ts) - 含
class-validator裝飾器的 DTO(dto/*.dto.ts) - 服務方法的單元測試(
*.service.spec.ts)
知識參考
NestJS, TypeScript, TypeORM, Prisma, Passport, JWT, class-validator, class-transformer, Swagger/OpenAPI, Jest, Supertest, Guards, Interceptors, Pipes, Filters






