nestjs-expert

nestjs-expert

熱門

建立並設定 NestJS 模組、控制器、服務、DTO、守衛與攔截器,適用於企業級 TypeScript 後端應用程式。在建構 NestJS REST API 或 GraphQL 服務、實作依賴注入、搭建模組化架構、加入 JWT/Passport 驗證、整合 TypeORM 或 Prisma,以及處理 .module.ts、.controller.ts 與 .service.ts 檔案時使用。亦可用於守衛、攔截器、管道、驗證、Swagger 文件,以及 NestJS 專案的單元測試與端對端測試。

1.1萬星標
965分支
更新於 2026/5/20
SKILL.md
readonlyread-only
name
nestjs-expert
description

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 後端應用程式。

核心工作流程

  1. 分析需求 — 識別模組、端點、實體與關聯
  2. 設計結構 — 規劃模組組織與模組間的依賴關係
  3. 實作 — 建立模組、服務與控制器,並正確進行 DI 接線
  4. 安全防護 — 加入守衛、驗證管道與驗證機制
  5. 驗證 — 執行 npm run lintnpm run test,並透過 nest info 確認 DI 圖
  6. 測試 — 為服務撰寫單元測試,為控制器撰寫端對端測試

參考指南

根據情境載入詳細指引:

主題 參考文件 載入時機
控制器 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 例外(NotFoundExceptionConflictException 等)
  • 使用 @ApiTags@ApiOperation 與回應裝飾器記錄所有端點
  • 使用 Test.createTestingModule 為每個服務方法撰寫單元測試
  • 透過 ConfigModuleprocess.env 儲存所有設定值;絕不寫死

禁止事項

  • 在回應中暴露密碼、機密或內部堆疊追蹤
  • 接受未經驗證的使用者輸入 — 務必套用 ValidationPipe
  • 使用 any 型別,除非絕對必要且有文件說明
  • 在模組之間建立循環依賴 — 僅在最後手段使用 forwardRef()
  • 在原始碼中寫死主機名稱、連接埠或憑證
  • 跳過服務方法中的錯誤處理

輸出模板

實作 NestJS 功能時,依下列順序提供:

  1. 模組定義(.module.ts
  2. 含 Swagger 裝飾器的控制器(.controller.ts
  3. 含型別化錯誤處理的服務(.service.ts
  4. class-validator 裝飾器的 DTO(dto/*.dto.ts
  5. 服務方法的單元測試(*.service.spec.ts

知識參考

NestJS, TypeScript, TypeORM, Prisma, Passport, JWT, class-validator, class-transformer, Swagger/OpenAPI, Jest, Supertest, Guards, Interceptors, Pipes, Filters

文件