用于处理路由请求
路由的三种参数 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¶m=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
}
就是提供方法 哪里需要使用这个方法就在哪里进行注入
实则拿 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))
安装配置依赖
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
}
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 {}
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 } })
}
}
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'
}
}