首页 景点排名文章正文

NestJs 从入门到实战项目笔记

景点排名 2025年11月03日 17:57 2 admin

C controller 控制

用于处理路由请求

路由的三种参数 Param Query Body

Param: restful API 参数

Query:url 参数

Body:post 参数

Param 就是获取 /xxx/:id

@Get('/data/:id')getData(@Param() param): string { #技术分享  console.log(' ~ AppController ~ getData ~ param:', param)  return 'data' +}  @Controller('user') export class UserController { @Get('/:id') getUser(@Param('id', ParseIntPipe) id: number) { console.log(' ~ UserController ~ id:', typeof id)  return 'get user' + id } } 

Body

@Post('/data')  postData(@Body() body): string {    console.log(' ~ AppController ~ postData ~ body:', body)    return 'post data'  }

Query /xxx/xxx?id=xxx&param=222

@Get('/data/:id')  getData(@Param() param, @Query() query): string {    console.log(' ~ AppController ~ getData ~ param:', param)    console.log(' ~ AppController ~ getData ~ query:', query)    return 'data' + param.id  }

providers 提供函数方法

就是提供方法 哪里需要使用这个方法就在哪里进行注入

其实拿 koa2 来进行举例就是

controller ​是进行路由对接的 然后执行具体的函数方法 是在 service 里面执行的 数据库的修改就是进一层的里

import { Module } from '@nestjs/common'import { AppController } from './app.controller'import { AppService } from './app.service'@Module({  imports: [],  controllers: [AppController],  providers: [AppService],})export class AppModule {}
@Get('/data/:id')  getData(@Param() param): string {    return this.appService.getData(param)  }
import { Injectable } from '@nestjs/common'@Injectable()export class AppService {  getData(param: any) {    console.log(' ~ AppService ~ getData ~ param:', param)    return 'data' + param.id  }}

异常处理器

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'import { Request, Response } from 'express'@Catch(HttpException)export class HttpExceptionFilter implements ExceptionFilter {  catch(exception: HttpException, host: ArgumentsHost) {    const ctx = host.switchToHttp()    const response = ctx.getResponse<Response>()    const request = ctx.getRequest<Request>()    const status = exception.getStatus()    response.status(status).json({      statusCode: status,      message: exception.message,      type: 'error',      timestamp: new Date().toISOString(),      path: request.url,    })  }}

main.ts

import { NestFactory } from '@nestjs/core'import { AppModule } from './app.module'import { HttpExceptionFilter } from './common/exception/http-exception.filter'import { VersioningType } from '@nestjs/common'async function bootstrap() {  const app = await NestFactory.create(AppModule)  app.setGlobalPrefix('api')  app.enableVersioning({ type: VersioningType.URI, defaultVersion: '1' })  app.useGlobalFilters(new HttpExceptionFilter())  await app.listen(3000)}bootstrap().catch((err) => console.error(err))

C config 配置文件

安装配置依赖

pnpm add @nestjs/config

根目录下创建配置文件 .env (该文件不进行提交) 我们创建.env.example 进行提交到代码仓库

.env

APP_NAME=nest-admin​DB_TYPE=mysql DB_HOST=localhost DB_PORT=3306 DB_USERNAME= DB_PASSWORD= DB_DATABASE= DB_SYNCHRONIZE=false

创建 config 模块文件

./common/config

import { registerAs } from '@nestjs/config'export default registerAs('app', () => {  return {    name: process.env.APP_NAME,      }})
import { registerAs } from '@nestjs/config'export default registerAs('database', () => {  return {    type: process.env.DB_TYPE || 'mysql',    host: process.env.DB_HOST || 'localhost',    port: parseInt(process.env.DB_PORT, 10) || 3306,    username: process.env.DB_USERNAME,    password: process.env.DB_PASSWORD,    database: process.env.DB_DATABASE,    synchronize: process.env.DB_SYNCHRONIZE === 'true',  }})
import appConfig from './app.config'import dbConfig from './db.config'export default [appConfig, dbConfig]

再app.module.ts 进行导入使用

import { Module } from '@nestjs/common'import { AppController } from './app.controller'import { AppService } from './app.service'import { UserModule } from './modules/user/user.module'import { AuthController } from './modules/auth/auth.controller'import { AuthModule } from './modules/auth/auth.module'import { ConfigModule } from '@nestjs/config'import config from './common/config'@Module({  imports: [    ConfigModule.forRoot({      isGlobal: true,      load: [...config],    }),    UserModule,    AuthModule,  ],  controllers: [AppController, AuthController],  providers: [AppService],})export class AppModule {}

再具体的模块之中进行使用

import { Controller, Get, Inject } from '@nestjs/common'import { ConfigType } from '@nestjs/config'import appConfig from './common/config/app.config'@Controller()export class AppController {  constructor(    private readonly appService: AppService,        @Inject(appConfig.KEY) private readonly app: ConfigType<typeof appConfig>,  ) {}  @Get('/test')  getTest(): string {    console.log(' ~ AppController ~ getTest ~ this.app.name:', this.app)    return this.app.name  }}

连接数据库与操作流程

mysql 数据库创建

数据库名: admin-dev字符集: utf8排序规则: utf8 general ci
pnpm install --save @nestjs/typeorm typeorm mysql2
  • 连接数据库
import { Module } from '@nestjs/common'import { AppController } from './app.controller'import { AppService } from './app.service'import { UserModule } from './modules/user/user.module'import { AuthController } from './modules/auth/auth.controller'import { AuthModule } from './modules/auth/auth.module'import { ConfigModule, ConfigService } from '@nestjs/config'import config from './common/config'import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'@Module({  imports: [    ConfigModule.forRoot({      isGlobal: true,      load: [...config],    }),    TypeOrmModule.forRootAsync({      inject: [ConfigService],      useFactory: (configService: ConfigService) =>({ type: configService.get('database.type'), host: configService.get('database.host'), port: configService.get('database.port'), username: configService.get('database.username'), password: configService.get('database.password'), database: configService.get('database.database'), synchronize: configService.get('database.synchronize'), autoLoadEntities: true, }) as TypeOrmModuleOptions, }), UserModule, AuthModule, ], controllers: [AppController, AuthController], providers: [AppService], }) export class AppModule {} 
  • 定义数据模型
import { Column, Entity, PrimaryGeneratedColumn, Unique } from 'typeorm'@Entity('admin_user')export class User {  @PrimaryGeneratedColumn()  id: number  @Column()  @Unique(['username'])  username: string  @Column()  password: string  @Column()  role: string  @Column()  nickname: string  @Column()  active: boolean}
  • 当前哪一个module需要使用就引入 实体
import { Module } from '@nestjs/common'import { UserController } from './user.controller'import { TypeOrmModule } from '@nestjs/typeorm'import { User } from './user.entity'import { UserService } from './user.service'@Module({  imports: [TypeOrmModule.forFeature([User])],  controllers: [UserController],  providers: [UserService],})export class UserModule {}
  • 再具体模块的service进行实体使用
import { Injectable } from '@nestjs/common'import { InjectRepository } from '@nestjs/typeorm'import { User } from './user.entity'import { Repository } from 'typeorm'@Injectable()export class UserService {  constructor(        @InjectRepository(User)    private readonly userRepository: Repository<User>,  ) {}  findOne(id: number) {        return this.userRepository.findOne({ where: { id } })  }}
  • service 查询然后返回给controller进行使用
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common'import { UserService } from './user.service'@Controller('user')export class UserController {    constructor(private readonly userService: UserService) {}  @Get('/:id')    getUser(@Param('id', ParseIntPipe) id: number) {    return this.userService.findOne(id)  }}

守卫/全局守卫

​nest g gu modules/auth
import { Module } from '@nestjs/common'import { AuthService } from './auth.service'import { AuthController } from './auth.controller'import { APP_GUARD } from '@nestjs/core'import { AuthGuard } from './auth.guard'@Module({  controllers: [AuthController],  providers: [    AuthService,    {            provide: APP_GUARD,      useClass: AuthGuard,    },  ],})export class AuthModule {}

如果只是定义单个的守卫 那么就不需要再 这个module里面写任何东西 只需要创建一个守卫 然后哪里需要哪里注入即可

这里我们注册的是全局路由守卫 就是每一个路由请求都会进入到这个守卫里面

  • 定义一个聚合装饰器,将标记公共装饰器和守卫装饰器聚合
import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common'import { AuthGuard } from './auth.guard'export const IS_PUBLIC_KEY = 'isPublic'export function Auth() {        return applyDecorators(SetMetadata(IS_PUBLIC_KEY, true), UseGuards(AuthGuard))}
  • 全局守卫(基础版本) 固定写法课参照文档 全局守卫
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'import { Reflector } from '@nestjs/core'import { Observable } from 'rxjs'import { IS_PUBLIC_KEY } from './auth.decorator'@Injectable()export class AuthGuard implements CanActivate {  constructor(private reflector: Reflector) {}  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [      context.getHandler(),      context.getClass(),    ])        if (isPublic) {      return true    }    return false  }}

使用

import { Controller, Post } from '@nestjs/common'import { Auth } from './auth.decorator'@Controller('auth')export class AuthController {  @Auth()    @Post('login')  login() {    return 'login'  }}

发表评论

长征号 Copyright © 2013-2024 长征号. All Rights Reserved.  sitemap