Skip to content
第 168 / 250 章Node⏱ 10 分钟阅读

第 168 章:第一个 NestJS 应用

学习目标

  • 理解 NestJS 启动流程
  • 掌握 main.ts 配置
  • 学会添加第一个路由
  • 实现简单的数据返回

一、Hello World 进阶版

1.1 创建路由

typescript
// app.controller.ts
import { Controller, Get, Param, Query, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';

@Controller('api')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('hello')
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('hello/:name')
  getHelloName(@Param('name') name: string): string {
    return this.appService.getHelloName(name);
  }

  @Get('search')
  search(@Query('q') query: string) {
    return { query, results: [] };
  }

  @Post('echo')
  echo(@Body() body: any) {
    return { received: body };
  }
}

1.2 测试

bash
# 启动
pnpm run start:dev

# 测试
curl http://localhost:3000/api/hello
# Hello NestJS!

curl http://localhost:3000/api/hello/Tom
# Hello, Tom!

curl "http://localhost:3000/api/search?q=nest"
# {"query":"nest","results":[]}

curl -X POST http://localhost:3000/api/echo \
  -H "Content-Type: application/json" \
  -d '{"name":"Tom"}'
# {"received":{"name":"Tom"}}

二、统一返回格式

typescript
// common/result.ts
export class Result<T> {
  code: number;
  message: string;
  data: T;
  timestamp: number = Date.now();

  static ok<T>(data: T): Result<T> {
    return { code: 200, message: 'OK', data, timestamp: Date.now() };
  }

  static fail<T = null>(code: number, message: string, data?: T): Result<T> {
    return { code, message, data: data as T, timestamp: Date.now() };
  }
}
typescript
// app.controller.ts
import { Result } from './common/result';

@Get('hello')
getHello(): Result<string> {
  return Result.ok(this.appService.getHello());
}

三、添加全局前缀

typescript
// main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix('api');  // ① 所有路由加 /api 前缀
  await app.listen(3000);
}

四、跨域配置

bash
pnpm add cors
typescript
// main.ts
import cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors({
    origin: ['http://localhost:5173', 'https://your-domain.com'],
    credentials: true,
  });
  await app.listen(3000);
}

五、环境变量

bash
pnpm add @nestjs/config
typescript
// app.module.ts
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,        // 全局可用
      envFilePath: '.env',    // 配置文件路径
    }),
  ],
  ...
})
export class AppModule {}
env
# .env
PORT=3000
DATABASE_URL=postgres://user:pass@localhost:5432/db
JWT_SECRET=your-secret
typescript
// main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const config = app.get(ConfigService);
  await app.listen(config.get('PORT', 3000));
}

六、第一个完整示例

typescript
// src/user/user.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';

interface User {
  id: number;
  name: string;
  email: string;
}

@Controller('users')
export class UserController {
  private users: User[] = [
    { id: 1, name: 'Tom', email: 'tom@x.com' },
    { id: 2, name: 'Jerry', email: 'jerry@x.com' },
  ];

  @Get()
  findAll() {
    return { code: 200, data: this.users };
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    const user = this.users.find(u => u.id === Number(id));
    if (!user) return { code: 404, message: 'Not found' };
    return { code: 200, data: user };
  }

  @Post()
  create(@Body() body: Omit<User, 'id'>) {
    const newUser: User = {
      id: this.users.length + 1,
      ...body,
    };
    this.users.push(newUser);
    return { code: 201, data: newUser };
  }
}

七、热重载与日志

start:dev 模式自动监听文件变化,日志彩色输出。

typescript
// app.service.ts
import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class AppService {
  private readonly logger = new Logger(AppService.name);

  getHello(): string {
    this.logger.log('getHello called');  // ① 日志
    this.logger.warn('warning');
    this.logger.error('error', 'stack');
    this.logger.debug('debug');
    return 'Hello NestJS!';
  }
}

八、本章小结

概念关键
启动NestFactory.create(AppModule)
路由装饰器@Get() @Post()
参数装饰器@Param() @Query() @Body()
全局前缀app.setGlobalPrefix('api')
跨域app.enableCors()
环境变量@nestjs/config

动手练习

  1. 创建一个 /api/users 的 GET 接口,返回 3 个用户
  2. 添加 POST 接口创建用户
  3. 添加全局前缀 /api
  4. 用 curl 测试所有接口

推荐阅读


下一章:第 169 章:控制器(Controller)详解

本站基于 VitePress 构建 · 由 Codebook 团队维护